diff options
Diffstat (limited to 'src/cmd/grap/grapl.lx')
-rw-r--r-- | src/cmd/grap/grapl.lx | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/src/cmd/grap/grapl.lx b/src/cmd/grap/grapl.lx new file mode 100644 index 00000000..0023aded --- /dev/null +++ b/src/cmd/grap/grapl.lx @@ -0,0 +1,213 @@ +%Start A str def thru sh + +%{ +#undef input +#undef unput +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include "grap.h" +#include "y.tab.h" + +extern struct symtab symtab[]; + +int yyback(int *, int); +int yylook(void); +int yywrap(void); +void shell_init(void), shell_exec(void), shell_text(char *); + +#define CADD cbuf[clen++] = yytext[0]; \ + if (clen >= CBUFLEN-1) { \ + ERROR "string too long", cbuf WARNING; BEGIN A; } +#define CBUFLEN 1500 +char cbuf[CBUFLEN]; +int clen, cflag; +int c, delim, shcnt; +%} + +A [a-zA-Z_] +B [a-zA-Z0-9_] +D [0-9] +WS [ \t] + +%% + if (yybgin-yysvec-1 == 0) { /* witchcraft */ + BEGIN A; + } + +<A>{WS} ; +<A>"\\"\n ; +<A>\n return(ST); +<A>";" return(ST); + +<A>line return(yylval.i = LINE); +<A>arrow { yylval.i = ARROW; return(LINE); } +<A>circle return(yylval.i = CIRCLE); +<A>frame return(FRAME); +<A>tick(s)? return(TICKS); +<A>grid(line)?(s)? return(GRID); +<A>coord(s)? return(COORD); +<A>log return(LOG); +<A>exp return(EXP); +<A>sin return(SIN); +<A>cos return(COS); +<A>atan2 return(ATAN2); +<A>sqrt return(SQRT); +<A>rand return(RAND); +<A>max return(MAX); +<A>min return(MIN); +<A>int return(INT); +<A>print return(PRINT); +<A>sprintf return(SPRINTF); +<A>pic{WS}.* { yylval.p = tostring(yytext+3); return(PIC); } +<A>graph{WS}.* { yylval.p = tostring(yytext+5); return(GRAPH); } + +<A>for return(FOR); +<A>^Endfor\n { endfor(); } +<A>do { yylval.p = delimstr("loop body"); BEGIN A; return(DOSTR); } + +<A>copy|include { return(COPY); } +<A>thru|through { BEGIN thru; return(THRU); } +<thru>{WS}+ ; +<thru>{A}{B}*|. { yylval.op = copythru(yytext); BEGIN A; return(DEFNAME); } +<A>until return(UNTIL); + +<A>if return(IF); +<A>then { yylval.p = delimstr("then part"); BEGIN A; return(THEN); } +<A>else { yylval.p = delimstr("else part"); BEGIN A; return(ELSE); } + +<A>next return(NEXT); +<A>draw return(yylval.i = DRAW); +<A>new return(yylval.i = NEW); +<A>plot return(yylval.i = PLOT); +<A>label(s)? return(LABEL); +<A>x return(X); +<A>y return(Y); + +<A>top { yylval.i = TOP; return SIDE; } +<A>bot(tom)? { yylval.i = BOT; return SIDE; } +<A>left { yylval.i = LEFT; return SIDE; } +<A>right { yylval.i = RIGHT; return SIDE; } +<A>up return(yylval.i = UP); +<A>down return(yylval.i = DOWN); +<A>across return(yylval.i = ACROSS); +<A>height|ht return(yylval.i = HEIGHT); +<A>wid(th)? return(yylval.i = WIDTH); +<A>rad(ius)? return(yylval.i = RADIUS); +<A>invis return(yylval.i = INVIS); +<A>dot(ted) return(yylval.i = DOT); +<A>dash(ed) return(yylval.i = DASH); +<A>solid return(yylval.i = SOLID); + +<A>ljust { yylval.i = LJUST; return JUST; } +<A>rjust { yylval.i = RJUST; return JUST; } +<A>above { yylval.i = ABOVE; return JUST; } +<A>below { yylval.i = BELOW; return JUST; } +<A>size return(yylval.i = SIZE); + +<A>from return(yylval.i = FROM); +<A>to return(yylval.i = TO); +<A>by|step return(yylval.i = BY); +<A>at return(yylval.i = AT); +<A>with return(yylval.i = WITH); +<A>in return(yylval.i = IN); +<A>out return(yylval.i = OUT); +<A>off return(yylval.i = OFF); + +<A>sh{WS}+ { BEGIN sh; + if ((delim = input()) == '{') { + shcnt = 1; + delim = '}'; + } + shell_init(); + } +<sh>{A}{B}* { + int c; + Obj *p; + if (yytext[0] == delim) { + shell_exec(); + BEGIN A; + } else { + p = lookup(yytext, 0); + if (p != NULL && p->type == DEFNAME) { + c = input(); + unput(c); + if (c == '(') + dodef(p); + else + pbstr(p->val); + } else + shell_text(yytext); + } + } +<sh>"{" { shcnt++; shell_text(yytext); } +<sh>"}" { if (delim != '}' || --shcnt > 0) + shell_text(yytext); + else { + shell_exec(); + BEGIN A; + } + } +<sh>.|\n { if (yytext[0] == delim) { + shell_exec(); + BEGIN A; + } else + shell_text(yytext); + } + +<A>define{WS}+ { BEGIN def; } +<def>{A}{B}* { definition(yytext); BEGIN A; } + +<A>({D}+("."?){D}*|"."{D}+)((e|E)("+"|-)?{D}+)?i? { + yylval.f = atof(yytext); return(NUMBER); } + +<A>^"."[^0-9].* { if (yytext[1] == 'G' && yytext[2] == '2') { + yylval.i = yytext[2]; + return(EOF); + } else { + yylval.p = tostring(yytext); + return(PIC); + } + } + +<A>{A}{B}* { + int c; + Obj *p; + p = lookup(yytext, 1); + if (p->type == DEFNAME) { + c = input(); + unput(c); + if (c == '(') /* it's name(...) */ + dodef(p); + else /* no argument list */ + pbstr(p->val); + } else { + yylval.op = p; + return p->type; /* NAME or VARNAME */ + } + } + +<A>"==" return(EQ); +<A>">=" return(GE); +<A>"<=" return(LE); +<A>"!=" return(NE); +<A>">" return(GT); +<A>"<" return(LT); +<A>"&&" return(AND); +<A>"||" return(OR); +<A>"!" return(NOT); + +<A>\" { BEGIN str; clen = 0; } + +<A>#.* ; + +<A>. { yylval.i = yytext[0]; return(yytext[0]); } + +<str>\" { BEGIN A; cbuf[clen] = 0; + yylval.p = tostring(cbuf); return(STRING); } +<str>\n { ERROR "newline in string" WARNING; BEGIN A; return(ST); } +<str>"\\\"" { cbuf[clen++] = '\\'; cbuf[clen++] = '"'; } +<str>"\\\\" { cbuf[clen++] = '\\'; cbuf[clen++] = '\\'; } +<str>. { CADD; } + +%% |