::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: parser.y :: %{ // other includes plus... #include "treeUtils.h" #include "scanType.h" #include "ourGetopt.h" // // YY STUFF // extern int yylex(); extern FILE *yyin; // write a nice error message #define YYERROR_VERBOSE void yyerror(const char *msg) { numErrors++; printf("ERROR(%d): %s\n", line, msg); } // // UTILS // TreeNode *addSibling(TreeNode *t, TreeNode *s) { ... } void setType(TreeNode *t, ExpType type, bool isStatic) { ... } // // DATA // // the syntax tree goes here TreeNode *syntaxTree; // // // // // // // // // // // // // // // // // %} // these types here will appear in the parser.tab.h!!! So the includes for them // MUST come before parser.tab.h! You may have other types in here if you like %union { TokenData *tokenData; TreeNode *tree; } // // TOKENS TYPES for both terminals and nonterminals in the grammar. If you use a $ variable // referring to a terminal or nonterminal then it goes here // %type ... // nonterminals %token ... // terminals and maybe some nonterminals %% grammar goes here that builds the tree %% ... int main(int argc, char *argv[]) { ... while (1) { // hunt for a string of options while ((c = ourGetopt(argc, argv, possibleArgs)) != EOF) { switch (c) { case 'd': yydebug=1; break; case 'p': printSyntaxTree=true; break; ... case 'h': case '?': default: usage(); exit(1); } } // pick off a nonoption if (optind TREE yyparse(); if (printSyntaxTree) printTree(stdout, syntaxTree, false, false); ... return 0; } ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: parser.l :: %{ #include "treeNodes.h" // tree node stuff needed by parser.tab.h (do before tab.h file) #include "scanType.h" // token stuff needed to talk between scanner and parser #include "parser.tab.h" // results of Bison compile ... // pretreat any token values and do any special processing int setValue(int linenum, int tokenClass, char *svalue) { yylval.tokenData = new TokenData; yylval.tokenData->tokenclass = tokenClass; ... return tokenClass; } %} %option noyywrap %% [\%\(\)\*\+\,\-\/\:\;\<\=\>\?\[\]\{\}] { return setValue(line, yytext[0], yytext); } // single char tokens "!=" { return setValue(line, NOTEQ, yytext); } ... %% ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: scanType.h :: // // SCANNER TOKENDATA // struct TokenData { int tokenclass; // token class int linenum; // line where found ... }; ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: treeNodes.h :: // // SYNTAX TREE DESCRIPTION inspired by Louden // // the exact type of the token or node involved. These are divided into // various "kinds" in the typedefs that follow // Kinds of Operators // these are the token numbers for the operators same as in flex typedef int OpKind; // Kinds of Statements typedef enum {DeclK, StmtK, ExpK} NodeKind; // Subkinds of Declarations typedef enum {VarK, FuncK, ParamK} DeclKind; // Subkinds of Statements typedef enum {NullK, ElsifK, IfK, WhileK, LoopK, LoopForeverK, CompoundK, RangeK, ReturnK, BreakK} StmtKind; // Subkinds of Expressions typedef enum {OpK, ConstantK, IdK, AssignK, InitK, CallK} ExpKind; // ExpType is used for type checking (Void means no type or value, UndefinedType means undefined) typedef enum {Void, Integer, Boolean, Char, CharInt, Equal, UndefinedType} ExpType; // What kind of scoping is used? (decided during typing) typedef enum {None, Local, Global, Parameter, LocalStatic} VarKind; #define MAXCHILDREN 3 // no more than 3 children allowed struct TreeNode { ... }; ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: TreeUtils.h :: #include "treeNodes.h" #include "scanType.h" ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :: TreeUtils.cpp :: // utilities to build the tree #include "treeUtils.h"