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