%{ /* * Changes by Gunnar Ritter, Freiburg i. Br., Germany, October 2005. * * Derived from Plan 9 v4 /sys/src/cmd/grap/ * * Copyright (C) 2003, Lucent Technologies Inc. and others. * All Rights Reserved. * * Distributed under the terms of the Lucent Public License Version 1.02. */ /* Sccsid @(#)grapl.l 1.4 (gritter) 11/22/05 */ %} %Start A str def thru sh %{ #ifndef FLEX_SCANNER #undef input #undef unput #endif /* !FLEX_SCANNER */ #include #include #include #include #include "grap.h" #include "y.tab.h" #ifdef FLEX_SCANNER #undef YY_INPUT #define YY_INPUT(buf, result, max_size) { \ int c = xxinput(); \ result = (c == EOF || c == 0) ? YY_NULL : (buf[0] = c, 1); \ } #define witchcraft YY_START #else /* !FLEX_SCANNER */ #define witchcraft yybgin-yysvec-1 #endif /* !FLEX_SCANNER */ 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) { \ WARNING("string too long", cbuf); 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 (witchcraft == 0) { BEGIN A; } {WS} ; "\\"\n ; \n return(ST); ";" return(ST); line return(yylval.i = LINE); arrow { yylval.i = ARROW; return(LINE); } circle return(yylval.i = CIRCLE); frame return(FRAME); tick(s)? return(TICKS); grid(line)?(s)? return(GRID); coord(s)? return(COORD); log return(LOG); exp return(EXP); sin return(SIN); cos return(COS); atan2 return(ATAN2); sqrt return(SQRT); rand return(RAND); max return(MAX); min return(MIN); int return(INT); print return(PRINT); sprintf return(SPRINTF); pic{WS}.* { yylval.p = tostring(yytext+3); return(PIC); } graph{WS}.* { yylval.p = tostring(yytext+5); return(GRAPH); } for return(FOR); ^Endfor\n { endfor(); } do { yylval.p = delimstr("loop body"); BEGIN A; return(DOSTR); } copy|include { return(COPY); } thru|through { BEGIN thru; return(THRU); } {WS}+ ; {A}{B}*|. { yylval.op = copythru(yytext); BEGIN A; return(DEFNAME); } until return(UNTIL); if return(IF); then { yylval.p = delimstr("then part"); BEGIN A; return(THEN); } else { yylval.p = delimstr("else part"); BEGIN A; return(ELSE); } next return(NEXT); draw return(yylval.i = DRAW); new return(yylval.i = NEW); plot return(yylval.i = PLOT); label(s)? return(LABEL); x return(X); y return(Y); top { yylval.i = TOP; return SIDE; } bot(tom)? { yylval.i = BOT; return SIDE; } left { yylval.i = LEFT; return SIDE; } right { yylval.i = RIGHT; return SIDE; } up return(yylval.i = UP); down return(yylval.i = DOWN); across return(yylval.i = ACROSS); height|ht return(yylval.i = HEIGHT); wid(th)? return(yylval.i = WIDTH); rad(ius)? return(yylval.i = RADIUS); invis return(yylval.i = INVIS); dot(ted) return(yylval.i = DOT); dash(ed) return(yylval.i = DASH); solid return(yylval.i = SOLID); ljust { yylval.i = LJUST; return JUST; } rjust { yylval.i = RJUST; return JUST; } above { yylval.i = ABOVE; return JUST; } below { yylval.i = BELOW; return JUST; } size return(yylval.i = SIZE); from return(yylval.i = FROM); to return(yylval.i = TO); by|step return(yylval.i = BY); at return(yylval.i = AT); with return(yylval.i = WITH); in return(yylval.i = IN); out return(yylval.i = OUT); off return(yylval.i = OFF); sh{WS}+ { BEGIN sh; if ((delim = input()) == '{') { shcnt = 1; delim = '}'; } shell_init(); } {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(); xxunput(c); if (c == '(') dodef(p); else pbstr(p->val); } else shell_text(yytext); } } "{" { shcnt++; shell_text(yytext); } "}" { if (delim != '}' || --shcnt > 0) shell_text(yytext); else { shell_exec(); BEGIN A; } } .|\n { if (yytext[0] == delim) { shell_exec(); BEGIN A; } else shell_text(yytext); } define{WS}+ { BEGIN def; } {A}{B}* { definition(yytext); BEGIN A; } ({D}+("."?){D}*|"."{D}+)((e|E)("+"|-)?{D}+)?i? { yylval.f = atof(yytext); return(NUMBER); } ^"."[^0-9].* { if (yytext[1] == 'G' && yytext[2] == '2') { yylval.i = yytext[2]; return(EOF); } else { yylval.p = tostring(yytext); return(PIC); } } {A}{B}* { int c; Obj *p; p = lookup(yytext, 1); if (p->type == DEFNAME) { c = input(); xxunput(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 */ } } "==" return(EQ); ">=" return(GE); "<=" return(LE); "!=" return(NE); ">" return(GT); "<" return(LT); "&&" return(AND); "||" return(OR); "!" return(NOT); \" { BEGIN str; clen = 0; } #.* ; . { yylval.i = yytext[0]; return(yytext[0]); } \" { BEGIN A; cbuf[clen] = 0; yylval.p = tostring(cbuf); return(STRING); } \n { WARNING("newline in string"); BEGIN A; return(ST); } "\\\"" { cbuf[clen++] = '\\'; cbuf[clen++] = '"'; } "\\\\" { cbuf[clen++] = '\\'; cbuf[clen++] = '\\'; } . { CADD; } %% #ifdef FLEX_SCANNER void xxcruft(void) { unput(0); } #endif /* FLEX_SCANNER */