123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- %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; }
- %%
|