1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | /* SI 413 Fall 2012 * Lab 6 * Parser for pat that just shows the parse tree * YOUR NAME HERE * PARTNER NAME HERE */ %code requires { #include <cstdlib> #include <iostream> #include "colorout.hpp" #include "parsetree.hpp" using namespace std; // This says that semantic values of tokens should be ParseTree pointers. #define YYSTYPE ParseTree* int yylex(); extern colorout resout; extern colorout errout; } %code { int yyerror(const char *p) { errout << "Parser error: " << p << endl; exit(3); } ParseTree* tree; // This global will be set to the whole parse tree. // Global variable to indicate to stop parsing. bool done = false; // These are the colored output streams to make things all pretty. colorout resout(1, 'u'); colorout errout(2, 'r'); } /* Tell bison to give descriptive error mesages. */ %error-verbose /* This defines the tokens. You will have to change this to set their precedence and associativity! */ %token STOP FOLD COLON REV SYM NAME LB RB %% /*Note: YYACCEPT is a bison macro that just tells it to quit parsing.*/ S: seq STOP { tree = $1; YYACCEPT; } | { done = true;; } seq: seq FOLD catseq {$$ = new ParseTree("seq",$1,$2,$3);} | catseq {$$ = new ParseTree("seq",$1);} catseq: catseq opseq {$$ = new ParseTree("catseq",$1,$2);} | opseq {$$ = new ParseTree("catseq",$1);} opseq: opseq COLON NAME {$$ = new ParseTree("opseq",$1,$2,$3);} | opseq REV {$$ = new ParseTree("opseq",$1,$2);} | atom {$$ = new ParseTree("opseq",$1);} atom: SYM {$$ = new ParseTree("atom",$1);} | NAME {$$ = new ParseTree("atom",$1);} | LB seq RB {$$ = new ParseTree("atom",$1,$2,$3);} %% int main() { // This checks whether the output is a terminal. // If it is, we'll show trees as pdf files. bool tty = isatty(0) && isatty(2); while(true) { tree = NULL; yyparse(); if (done) break; if (tty) { tree->writeDot("pat.dot"); system("dot -Tpdf pat.dot > pat.pdf"); system("evince pat.pdf > /dev/null 2>&1 &"); } else { tree->writeTo(resout); } } // Try to kill off any parse tree windows that are hanging around system("kill `pgrep -f \"evince pat.pdf\"`"); return 0; } |