%{ #include extern FILE *yyin; %} %token ident %token charconst %token string %token num %token doublelessthan %token arrow %token INT %token CHAR %token CLASS %token PUBLIC %token PRIVATE %token VOID %token IF %token ELSE %token WHILE %token RETURN %token COUT %token CIN %% Start : Gitem | Start Gitem ; Gitem : CLASS ident '{' Classbody '}' | VOID ident '(' Plist | Type Optstar ident Girest ; Type : INT | CHAR | ident ; Optstar : /* empty */ | '*' ; Optarray : /* empty */ | '[' num ']' ; /* Added Optarray in second rule 4/6/2001 */ Vardecl : ';' | ',' Optstar ident Optarray Vardecl ; Fplist : ')' '{' Body '}' | Fplist1 '{' Body '}' ; Fplist1 : Type Optstar ident ')' | Type Optstar ident ',' Fplist1 ; Classbody : Citem | Classbody Citem ; Citem : Optscope VOID ident '(' Fplist | Optscope Type Optstar ident Cirest ; Optscope : /* empty */ | PUBLIC ':' | PRIVATE ':' ; Cirest : Optarray Vardecl | '(' Fplist ; Body : Bitem | Body Bitem /* not sure if this is LALR */ Bitem : VOID ident '(' Pplist | Type Optstar ident '(' Pplist | Type Optstar ident Optarray Vardecl | Statement Statement : MatchedStatement | UnmatchedStatement ; MatchedStatement : ';' | Lhsid '=' Expr ';' | Lhsid '(' Cplist ';' | IF '(' Expr ')' MatchedStatement ELSE MatchedStatement | WHILE '(' Expr ')' Statement | RETURN Expr ';' | COUT Couts ';' | CIN Cins ';' | '{' Stlist '}' ; UnmatchedStatement : IF '(' Expr ')' MatchedStatement | IF '(' Expr ')' UnmatchedStatement | IF '(' Expr ')' MatchedStatement ELSE UnmatchedStatement ; Stlist : /* empty */ | Statement Stlist ; Cplist : ')' | Cplist1 Cplist1 : Expr ')' | Expr ',' Cplist1 Lhsid : Lhsid1 | '*' Lhsid ; Lhsid1 : Lhsid1 arrow Lhsbase | Lhsid1 '.' Lhsbase | Lhsbase ; Lhsbase : ident | ident '[' Expr ']' ; Couts : /* empty */ | doublelessthan Expr Couts ; Cins : /* empty */ | '>' '>' Lhsid Cins ; Expr : Expr '|' '|' Expr1 | Expr1 ; Expr1 : Expr1 '&' '&' Expr2 | Expr2 ; Expr2 : Expr2 '=' '=' Expr3 | Expr2 '!' '=' Expr3 | Expr3 ; Expr3 : Expr3 '<' Expr4 | Expr3 '<' '=' Expr4 | Expr3 '>' Expr4 | Expr3 '>' '=' Expr4 | Expr4 ; Expr4 : Expr4 '+' Expr5 | Expr4 '-' Expr5 | Expr5 ; Expr5 : Expr5 '*' Expr6 | Expr5 '/' Expr6 | Expr5 '%' Expr6 | Expr6 ; Expr6 : '!' Expr7 | '+' Expr7 | '-' Expr7 | Expr7 ; /* Change to "charconst" to distinguish from keyword "char" - 4/6/2001 */ Expr7 : '(' Expr ')' | Lhsid | Lhsid '(' Cplist | '&' Lhsid | num | charconst | string ; /* This following is an update on the prototype vs fumction parameter list. This should be LALR. The following rules would replace Girest, Pplist, Pplist1, Pplist2, Pplist2a, Pplist3, Pplist3a and Pplist4 from above (Fplist is still used in the Classbody). */ Girest : Optarray Vardecl | '(' Plist ; Plist : ')' Forp | Type Optstar ')' ';' | Type Optstar ident ')' Forp | Type Optstar ',' Type Optstar Pl1 ')' ';' | Type Optstar ',' Type Optstar Pl1 ident Pl3 ')' ';' | Type Optstar ident ',' Type Optstar Pl2a ')' Forp | Type Optstar ident ',' Type Optstar Pl2 Pl3 ')' ';' ; Pl1 : /* empty */ | ',' Type Optstar Pl1 ; Pl2 : /* empty */ | ident ',' Type Optstar Pl2 ; Pl2a : ident | ident ',' Type Optstar Pl2a ; Pl3 : /* empty */ | ',' Type Optstar Optident Pl3 ; Optident : /* empty */ | ident ; Forp : ';' | '{' Body '}' ; Pplist : ')' ';' | Type Optstar Optident Pl3 ')' ';' ; %% main(int argc, char** argv) { if (argc == 2) yyin = fopen(argv[1], "r"); else { printf("Usage: %s input_filename\n", argv[0]); exit(1); } if (yyparse()) printf("Parsing failed\n"); else printf("Parsing successful\n"); } extern unsigned int line_number, column_number; int yyerror(char* err) { fprintf(stderr, "%s: line_number:%d column_number:%d\n", err, line_number, column_number); }