grapl.lx (4833B)
1 %Start A str def thru sh 2 3 %{ 4 #undef input 5 #undef unput 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <ctype.h> 9 #include "grap.h" 10 #include "y.tab.h" 11 12 int yyback(int *, int); 13 int yylook(void); 14 int yywrap(void); 15 void shell_init(void), shell_exec(void), shell_text(char *); 16 17 #define CADD cbuf[clen++] = yytext[0]; \ 18 if (clen >= CBUFLEN-1) { \ 19 ERROR "string too long" WARNING; BEGIN A; } 20 #define CBUFLEN 1500 21 char cbuf[CBUFLEN]; 22 int clen, cflag; 23 int c, delim, shcnt; 24 %} 25 26 A [a-zA-Z_] 27 B [a-zA-Z0-9_] 28 D [0-9] 29 WS [ \t] 30 31 %% 32 if (yybgin-yysvec-1 == 0) { /* witchcraft */ 33 BEGIN A; 34 } 35 36 <A>{WS} ; 37 <A>"\\"\n ; 38 <A>\n return(ST); 39 <A>";" return(ST); 40 41 <A>line return(yylval.i = LINE); 42 <A>arrow { yylval.i = ARROW; return(LINE); } 43 <A>circle return(yylval.i = CIRCLE); 44 <A>frame return(FRAME); 45 <A>tick(s)? return(TICKS); 46 <A>grid(line)?(s)? return(GRID); 47 <A>coord(s)? return(COORD); 48 <A>log return(LOG); 49 <A>exp return(EXP); 50 <A>sin return(SIN); 51 <A>cos return(COS); 52 <A>atan2 return(ATAN2); 53 <A>sqrt return(SQRT); 54 <A>rand return(RAND); 55 <A>max return(MAX); 56 <A>min return(MIN); 57 <A>int return(INT); 58 <A>print return(PRINT); 59 <A>sprintf return(SPRINTF); 60 <A>pic{WS}.* { yylval.p = tostring(yytext+3); return(PIC); } 61 <A>graph{WS}.* { yylval.p = tostring(yytext+5); return(GRAPH); } 62 63 <A>for return(FOR); 64 <A>^Endfor\n { endfor(); } 65 <A>do { yylval.p = delimstr("loop body"); BEGIN A; return(DOSTR); } 66 67 <A>copy|include { return(COPY); } 68 <A>thru|through { BEGIN thru; return(THRU); } 69 <thru>{WS}+ ; 70 <thru>{A}{B}*|. { yylval.op = copythru(yytext); BEGIN A; return(DEFNAME); } 71 <A>until return(UNTIL); 72 73 <A>if return(IF); 74 <A>then { yylval.p = delimstr("then part"); BEGIN A; return(THEN); } 75 <A>else { yylval.p = delimstr("else part"); BEGIN A; return(ELSE); } 76 77 <A>next return(NEXT); 78 <A>draw return(yylval.i = DRAW); 79 <A>new return(yylval.i = NEW); 80 <A>plot return(yylval.i = PLOT); 81 <A>label(s)? return(LABEL); 82 <A>x return(X); 83 <A>y return(Y); 84 85 <A>top { yylval.i = TOP; return SIDE; } 86 <A>bot(tom)? { yylval.i = BOT; return SIDE; } 87 <A>left { yylval.i = LEFT; return SIDE; } 88 <A>right { yylval.i = RIGHT; return SIDE; } 89 <A>up return(yylval.i = UP); 90 <A>down return(yylval.i = DOWN); 91 <A>across return(yylval.i = ACROSS); 92 <A>height|ht return(yylval.i = HEIGHT); 93 <A>wid(th)? return(yylval.i = WIDTH); 94 <A>rad(ius)? return(yylval.i = RADIUS); 95 <A>invis return(yylval.i = INVIS); 96 <A>dot(ted) return(yylval.i = DOT); 97 <A>dash(ed) return(yylval.i = DASH); 98 <A>solid return(yylval.i = SOLID); 99 100 <A>ljust { yylval.i = LJUST; return JUST; } 101 <A>rjust { yylval.i = RJUST; return JUST; } 102 <A>above { yylval.i = ABOVE; return JUST; } 103 <A>below { yylval.i = BELOW; return JUST; } 104 <A>size return(yylval.i = SIZE); 105 106 <A>from return(yylval.i = FROM); 107 <A>to return(yylval.i = TO); 108 <A>by|step return(yylval.i = BY); 109 <A>at return(yylval.i = AT); 110 <A>with return(yylval.i = WITH); 111 <A>in return(yylval.i = IN); 112 <A>out return(yylval.i = OUT); 113 <A>off return(yylval.i = OFF); 114 115 <A>sh{WS}+ { BEGIN sh; 116 if ((delim = input()) == '{') { 117 shcnt = 1; 118 delim = '}'; 119 } 120 shell_init(); 121 } 122 <sh>{A}{B}* { 123 int c; 124 Obj *p; 125 if (yytext[0] == delim) { 126 shell_exec(); 127 BEGIN A; 128 } else { 129 p = lookup(yytext, 0); 130 if (p != NULL && p->type == DEFNAME) { 131 c = input(); 132 unput(c); 133 if (c == '(') 134 dodef(p); 135 else 136 pbstr(p->val); 137 } else 138 shell_text(yytext); 139 } 140 } 141 <sh>"{" { shcnt++; shell_text(yytext); } 142 <sh>"}" { if (delim != '}' || --shcnt > 0) 143 shell_text(yytext); 144 else { 145 shell_exec(); 146 BEGIN A; 147 } 148 } 149 <sh>.|\n { if (yytext[0] == delim) { 150 shell_exec(); 151 BEGIN A; 152 } else 153 shell_text(yytext); 154 } 155 156 <A>define{WS}+ { BEGIN def; } 157 <def>{A}{B}* { definition(yytext); BEGIN A; } 158 159 <A>({D}+("."?){D}*|"."{D}+)((e|E)("+"|-)?{D}+)?i? { 160 yylval.f = atof(yytext); return(NUMBER); } 161 162 <A>^"."[^0-9].* { if (yytext[1] == 'G' && yytext[2] == '2') { 163 yylval.i = yytext[2]; 164 return(EOF); 165 } else { 166 yylval.p = tostring(yytext); 167 return(PIC); 168 } 169 } 170 171 <A>{A}{B}* { 172 int c; 173 Obj *p; 174 p = lookup(yytext, 1); 175 if (p->type == DEFNAME) { 176 c = input(); 177 unput(c); 178 if (c == '(') /* it's name(...) */ 179 dodef(p); 180 else /* no argument list */ 181 pbstr(p->val); 182 } else { 183 yylval.op = p; 184 return p->type; /* NAME or VARNAME */ 185 } 186 } 187 188 <A>"==" return(EQ); 189 <A>">=" return(GE); 190 <A>"<=" return(LE); 191 <A>"!=" return(NE); 192 <A>">" return(GT); 193 <A>"<" return(LT); 194 <A>"&&" return(AND); 195 <A>"||" return(OR); 196 <A>"!" return(NOT); 197 198 <A>\" { BEGIN str; clen = 0; } 199 200 <A>#.* ; 201 202 <A>. { yylval.i = yytext[0]; return(yytext[0]); } 203 204 <str>\" { BEGIN A; cbuf[clen] = 0; 205 yylval.p = tostring(cbuf); return(STRING); } 206 <str>\n { ERROR "newline in string" WARNING; BEGIN A; return(ST); } 207 <str>"\\\"" { cbuf[clen++] = '\\'; cbuf[clen++] = '"'; } 208 <str>"\\\\" { cbuf[clen++] = '\\'; cbuf[clen++] = '\\'; } 209 <str>. { CADD; } 210 211 %%