Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

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

%%