1 %Start A str def sc br thru sh 2 %e 1700 3 %k 120 4 %a 1800 5 %o 1500 6 %p 5000 7 %n 700 8 9 %{ 10 #undef input 11 #undef unput 12 #include <stdio.h> 13 #include <ctype.h> 14 #include "pic.h" 15 #include "y.tab.h" 16 17 extern float atof(); 18 extern struct symtab symtab[]; 19 extern char *filename, *copythru(); 20 21 #define CADD cbuf[clen++]=yytext[0]; if(clen>=CBUFLEN-1) {yyerror("string too long", cbuf); BEGIN A;} 22 #define CBUFLEN 500 23 char cbuf[CBUFLEN]; 24 int c, clen, cflag, delim; 25 int ifsw = 0; /* 1 if if statement in progress */ 26 %} 27 28 A [a-zA-Z_] 29 B [a-zA-Z0-9_] 30 D [0-9] 31 WS [ \t] 32 33 %% 34 switch (yybgin-yysvec-1) { /* witchcraft */ 35 case 0: 36 BEGIN A; 37 break; 38 case sc: 39 BEGIN A; 40 return('}'); 41 case br: 42 BEGIN A; 43 return(']'); 44 } 45 46 <A>{WS} ; 47 <A>"\\"\n ; 48 <A>\n { return(ST); } 49 <A>";" { return(ST); } 50 <A>"}" { BEGIN sc; return(ST); } 51 <A>"]" { BEGIN br; return(ST); } 52 53 <A>^".PS".* { if (curfile == infile) yyerror(".PS found inside .PS/.PE"); } 54 <A>^"."P[EF].* { if (curfile == infile) { 55 yylval.i = yytext[2]; 56 return(EOF); 57 } 58 } 59 <A>^".".* { yylval.p = tostring(yytext); return(TROFF); } 60 61 <A>print return(yylval.i = PRINT); 62 <A>box return(yylval.i = BOX); 63 <A>circle return(yylval.i = CIRCLE); 64 <A>arc return(yylval.i = ARC); 65 <A>ellipse return(yylval.i = ELLIPSE); 66 <A>arrow return(yylval.i = ARROW); 67 <A>spline return(yylval.i = SPLINE); 68 <A>line return(yylval.i = LINE); 69 <A>move return(yylval.i = MOVE); 70 <A>"[]" return(yylval.i = BLOCK); 71 <A>reset return(RESET); 72 <A>sprintf return(SPRINTF); 73 74 <A>same return(SAME); 75 <A>between return(BETWEEN); 76 <A>and return(AND); 77 78 <A>of ; 79 <A>the ; 80 <A>way ; 81 82 <A>"."(e|east) { yylval.i = EAST; return(CORNER); } 83 <A>"."(r|right) { yylval.i = EAST; return(CORNER); } 84 <A>"."(w|west) { yylval.i = WEST; return(CORNER); } 85 <A>"."(l|left) { yylval.i = WEST; return(CORNER); } 86 <A>"."(n|north) { yylval.i = NORTH; return(CORNER); } 87 <A>"."(t|top) { yylval.i = NORTH; return(CORNER); } 88 <A>"."(s|south) { yylval.i = SOUTH; return(CORNER); } 89 <A>"."(b|bot|bottom) { yylval.i = SOUTH; return(CORNER); } 90 <A>"."(c|center) { yylval.i = CENTER; return(CORNER); } 91 <A>".start" { yylval.i = START; return(CORNER); } 92 <A>".end" { yylval.i = END; return(CORNER); } 93 <A>".ne" { yylval.i = NE; return(CORNER); } 94 <A>".se" { yylval.i = SE; return(CORNER); } 95 <A>".nw" { yylval.i = NW; return(CORNER); } 96 <A>".sw" { yylval.i = SW; return(CORNER); } 97 98 <A>top" "+of { yylval.i = NORTH; return(CORNER); } 99 <A>north" "+of { yylval.i = NORTH; return(CORNER); } 100 <A>bottom" "+of { yylval.i = SOUTH; return(CORNER); } 101 <A>south" "+of { yylval.i = SOUTH; return(CORNER); } 102 <A>left" "+of { yylval.i = WEST; return(CORNER); } 103 <A>west" "+of { yylval.i = WEST; return(CORNER); } 104 <A>right" "+of { yylval.i = EAST; return(CORNER); } 105 <A>east" "+of { yylval.i = EAST; return(CORNER); } 106 <A>center" "+of { yylval.i = CENTER; return(CORNER); } 107 <A>start" "+of { yylval.i = START; return(CORNER); } 108 <A>end" "+of { yylval.i = END; return(CORNER); } 109 110 <A>height|ht { yylval.i = HEIGHT; return(ATTR); } 111 <A>width|wid { yylval.i = WIDTH; return(ATTR); } 112 <A>radius|rad { yylval.i = RADIUS; return(ATTR); } 113 <A>diameter|diam { yylval.i = DIAMETER; return(ATTR); } 114 <A>size { yylval.i = SIZE; return(ATTR); } 115 <A>left { yylval.i = LEFT; return(DIR); } 116 <A>right { yylval.i = RIGHT; return(DIR); } 117 <A>up { yylval.i = UP; return(DIR); } 118 <A>down { yylval.i = DOWN; return(DIR); } 119 <A>cw { yylval.i = CW; return(ATTR); } 120 <A>clockwise { yylval.i = CW; return(ATTR); } 121 <A>ccw { yylval.i = CCW; return(ATTR); } 122 <A>invis(ible)? { yylval.i = INVIS; return(ATTR); } 123 <A>dot(ted)? return(yylval.i = DOT); 124 <A>dash(ed)? return(yylval.i = DASH); 125 <A>chop return(yylval.i = CHOP); 126 127 <A>spread { yylval.i = SPREAD; return TEXTATTR; } 128 <A>fill { yylval.i = FILL; return TEXTATTR; } 129 <A>ljust { yylval.i = LJUST; return TEXTATTR; } 130 <A>rjust { yylval.i = RJUST; return TEXTATTR; } 131 <A>above { yylval.i = ABOVE; return TEXTATTR; } 132 <A>below { yylval.i = BELOW; return TEXTATTR; } 133 <A>center { yylval.i = CENTER; return TEXTATTR; } 134 135 <A>"<-" { yylval.i = HEAD1; return(HEAD); } 136 <A>"->" { yylval.i = HEAD2; return(HEAD); } 137 <A>"<->" { yylval.i = HEAD12; return(HEAD); } 138 139 <A>".x" return(yylval.i = DOTX); 140 <A>".y" return(yylval.i = DOTY); 141 <A>"."(ht|height) return(yylval.i = DOTHT); 142 <A>"."(wid|width) return(yylval.i = DOTWID); 143 <A>"."(rad|radius) return(yylval.i = DOTRAD); 144 145 <A>from return(yylval.i = FROM); 146 <A>to return(yylval.i = TO); 147 <A>at return(yylval.i = AT); 148 <A>by return(yylval.i = BY); 149 <A>with return(yylval.i = WITH); 150 <A>last return(yylval.i = LAST); 151 152 <A>log return(LOG); 153 <A>exp return(EXP); 154 <A>sin return(SIN); 155 <A>cos return(COS); 156 <A>atan2 return(ATAN2); 157 <A>sqrt return(SQRT); 158 <A>rand return(RAND); 159 <A>max return(MAX); 160 <A>min return(MIN); 161 <A>int return(INT); 162 163 <A>"==" return(EQ); 164 <A>">=" return(GE); 165 <A>"<=" return(LE); 166 <A>"!=" return(NEQ); 167 <A>">" return(GT); 168 <A>"<" return(LT); 169 <A>"&&" return(ANDAND); 170 <A>"||" return(OROR); 171 <A>"!" return(NOT); 172 173 <A>Here return(yylval.i = HERE); 174 175 <A>for return(FOR); 176 <A>^Endfor\n { endfor(); } 177 <A>do { yylval.p = delimstr("loop body"); return(DOSTR); } 178 179 <A>copy|include return(COPY); 180 <A>(thru|through){WS}+ { BEGIN thru; return(THRU); } 181 <thru>{A}{B}*|. { yylval.p = copythru(yytext); BEGIN A; return(DEFNAME); } 182 <A>until return(UNTIL); 183 184 <A>if { ifsw = 1; return(IF); } 185 <A>then { if (!ifsw) { yylval.i = THEN; return(ATTR); } 186 yylval.p = delimstr("then part"); ifsw = 0; 187 return(THENSTR); } 188 <A>else { yylval.p = delimstr("else part"); return(ELSESTR); } 189 190 <A>sh{WS}+ { BEGIN sh; 191 if ((delim = input()) == '{') delim = '}'; /* no nested {} */ 192 shell_init(); } 193 <sh>{A}{B}* { struct symtab *p; 194 if (yytext[0] == delim) { 195 shell_exec(); 196 BEGIN A; 197 } else { 198 p = lookup(yytext, 0); 199 if (p != NULL && p->s_type == DEFNAME) { 200 c = input(); 201 unput(c); 202 if (c == '(') 203 dodef(p); 204 else 205 pbstr(p->s_val.p); 206 } else 207 shell_text(yytext); 208 } 209 } 210 <sh>.|\n { if (yytext[0] == delim) { 211 shell_exec(); 212 BEGIN A; 213 } else 214 shell_text(yytext); 215 } 216 217 <A>define{WS}+ { BEGIN def; } 218 <def>{A}{B}* { definition(yytext); BEGIN A; } 219 <A>undef(ine)?{WS}+{A}{B}* { undefine(yytext); } 220 221 <A>first { yylval.i = 1; return(NTH); } 222 <A>{D}+(th|nd|rd|st) { yylval.i = atoi(yytext); return(NTH); } 223 <A>({D}+("."?){D}*|"."{D}+)((e|E)("+"|-)?{D}+)?i? { 224 yylval.f = atof(yytext); return(NUMBER); } 225 226 <A>{A}{B}* { struct symtab *p; 227 p = lookup(yytext); 228 if (p != NULL && p->s_type == DEFNAME) { 229 c = input(); 230 unput(c); 231 if (c == '(') /* it's name(...) */ 232 dodef(p); 233 else { /* no argument list */ 234 pbstr(p->s_val); 235 dprintf("pushing back `%s'\n", p->s_val); 236 } 237 } else if (islower(yytext[0])) { 238 yylval.p = tostring(yytext); 239 return(VARNAME); 240 } else { 241 yylval.p = tostring(yytext); 242 return(PLACENAME); 243 } 244 } 245 246 <A>\" { BEGIN str; clen=0; } 247 <str>\" { cbuf[clen]=0; yylval.p = tostring(cbuf); BEGIN A; return(TEXT); } 248 <str>\n { yyerror("newline in string"); BEGIN A; return(ST); } 249 <str>"\\\"" { cbuf[clen++]='"'; } 250 <str>"\\"t { cbuf[clen++]='\t'; } 251 <str>"\\\\" { cbuf[clen++]='\\'; } 252 <str>. { CADD; } 253 254 <A>#.* ; 255 256 <A>. return(yylval.i = yytext[0]); 257 258 %% 259