From bda779c6833885fb797d01fbf71f58b073ce664c Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Tue, 30 Mar 2010 15:37:51 +0200 Subject: [PATCH] ag: parser.y und scanner.lex von parser/ --- ag/parser.y | 275 +++++++++++++++++-------------------------------- ag/scanner.lex | 82 +++++++-------- 2 files changed, 131 insertions(+), 226 deletions(-) diff --git a/ag/parser.y b/ag/parser.y index 994b76c..181bc5a 100644 --- a/ag/parser.y +++ b/ag/parser.y @@ -1,201 +1,114 @@ %{ #include #include - #include - #include "symtable.h" %} -%start Input -%token FUNC END STRUCT VAR IF THEN ELSE WHILE DO RETURN OR NOT -%token ID NUM ASSIGN GREATER - -@autoinh symbols - -@attributes { char *name; } ID -@attributes { struct symbol *fields; struct symbol *symbols; } Program -@attributes { struct symbol *fields; } Ids Structdef -@attributes { struct symbol *pars; } Pars -@attributes { struct symbol *symbols; } Funcdef Stats Bool Expr Call Lexpr Field Term Plusterm Malterm Bterm Orterm Exprs -@attributes { struct symbol *in_symbols; struct symbol *out_symbols; } Stat - -@traversal @postorder c +%start Program +%token STRUCT END METHOD VAR IF THEN ELSE WHILE DO RETURN NOT OR THIS +%token IDENT NUM %% -Input: Program - @{ @i @Program.symbols@ = @Program.fields@; @} - - ; - -Program: Funcdef ';' Program - @{ - @i @Program.0.fields@ = @Program.1.fields@; - @} - - | Structdef ';' Program - @{ - @i @Program.0.fields@ = tab_merge(@Structdef.fields@, @Program.1.fields@, 1); - @} - - | - @{ @i @Program.fields@ = new_tab(); @} - - ; - -Funcdef: FUNC ID '(' Pars ')' Stats END - @{ @i @Stats.symbols@ = tab_merge(@Funcdef.symbols@, @Pars.pars@, 0); @} - - ; - -Structdef: STRUCT Ids END - @{ @i @Structdef.fields@ = @Ids.fields@; @} - - ; - -Ids: ID Ids - @{ @i @Ids.0.fields@ = tab_add_symbol(@Ids.1.fields@, @ID.name@, S_FIELD, 1); @} - - | - @{ @i @Ids.fields@ = new_tab(); @} - - ; - -Pars: Pars ',' ID - @{ @i @Pars.0.pars@ = tab_add_symbol(@Pars.1.pars@, @ID.name@, S_VAR, 0); @} - - | ID - @{ @i @Pars.pars@ = tab_add_symbol(new_tab(), @ID.name@, S_VAR, 0); @} - - | - @{ @i @Pars.pars@ = new_tab(); @} - - ; - -Stats: Stat ';' Stats - @{ - @i @Stat.in_symbols@ = @Stats.0.symbols@; - @i @Stats.1.symbols@ = @Stat.out_symbols@; - @} - - | - ; - -Stat: VAR ID ASSIGN Expr - @{ - @i @Stat.out_symbols@ = tab_add_symbol(clone_tab(@Stat.in_symbols@), @ID.name@, S_VAR, 0); - @i @Expr.symbols@ = @Stat.in_symbols@; - @} - - | Lexpr ASSIGN Expr - @{ - @i @Stat.out_symbols@ = @Stat.in_symbols@; - @i @Lexpr.symbols@ = @Stat.in_symbols@; - @i @Expr.symbols@ = @Stat.in_symbols@; - @} - - | IF Bool THEN Stats END - @{ - @i @Bool.symbols@ = @Stat.in_symbols@; - @i @Stats.symbols@ = @Stat.in_symbols@; - @i @Stat.out_symbols@ = @Stat.in_symbols@; - @} - - | IF Bool THEN Stats ELSE Stats END - @{ - @i @Bool.symbols@ = @Stat.in_symbols@; - @i @Stats.0.symbols@ = @Stat.in_symbols@; - @i @Stats.1.symbols@ = @Stat.in_symbols@; - @i @Stat.out_symbols@ = @Stat.in_symbols@; - @} - - | WHILE Bool DO Stats END - @{ - @i @Bool.symbols@ = @Stat.in_symbols@; - @i @Stats.symbols@ = @Stat.in_symbols@; - @i @Stat.out_symbols@ = @Stat.in_symbols@; - @} - - | Call - @{ - @i @Call.symbols@ = @Stat.in_symbols@; - @i @Stat.out_symbols@ = @Stat.in_symbols@; - @} - - | RETURN Expr - @{ - @i @Expr.symbols@ = @Stat.in_symbols@; - @i @Stat.out_symbols@ = @Stat.in_symbols@; - @} - - ; - -Lexpr: ID - @{ @c check_variable(@Lexpr.symbols@, @ID.name@); @} - - | Field - ; - -Expr: '-' Term - | Term - | Term Plusterm - | Term Malterm - ; - -Plusterm: '+' Term Plusterm - | '+' Term - ; - -Malterm: '*' Term Malterm - | '*' Term - ; - -Term: '(' Expr ')' - | ID - @{ @c check_variable(@Term.symbols@, @ID.name@); @} - - | NUM - | Call - | Field - ; - -Bool: Bterm - | Bterm Orterm - | NOT Bterm - ; - -Orterm: OR Bterm Orterm - | OR Bterm - ; - -Bterm: Term GREATER Term - | Term '=' Term - | '(' Bool ')' - ; - -Field: Term '.' ID - @{ @c check_field(@Field.symbols@, @ID.name@); @} - - ; - -Call: ID '(' Exprs ')' - | ID '(' ')' - ; - -Exprs: Expr - | Exprs ',' Expr - ; +Program: + Methoddef ';' Program + | Structdef ';' Program + | + ; + +Structdef: + STRUCT Idents END + ; + +Methoddef: + METHOD IDENT '(' Idents ')' Statseq END + ; + +Idents: + IDENT Idents + | + ; + +Statseq: + Statement ';' Statseq + | + ; + +Statement: + Lexpr ':=' Expr + | VAR IDENT ':=' Expr + | Expr + | IF Expr THEN Statseq END + | IF Expr THEN Statseq ELSE Statseq END + | WHILE Expr DO Statseq END + | RETURN Expr + ; + +Lexpr: + IDENT + | Term '.' IDENT + ; + +Expr: + Term + | NOT Term + | Term Minusterm + | Term Multerm + | Term Orterm + | Term '<' Term + | Term '=' Term + ; + +Minusterm: + '-' Term Minusterm + | '-' Term + ; + +Multerm: + '*' Term Multerm + | '*' Term + ; + +Orterm: + OR Term Orterm + | OR Term + ; + + +Term: + '(' Expr ')' + | NUM + | '-' NUM + | THIS + | IDENT + | Term '.' IDENT + | IDENT '(' Exprs ')' + | Term '.' IDENT '(' Exprs ')' + ; + +/* beachte dass hier auch "nichts" vorkommen kann + * sonst waer ein aufruf der art 'f()' nicht + * moeglich (leere parameterliste) */ +Exprs: + | Expr + | Exprs ',' Expr + ; %% extern int yylex(); extern int yylineno; -int yyerror(char *error_text) { - fprintf(stderr,"Line %i: %s\n",yylineno, error_text); +int yyerror(char *error_text) +{ + fprintf(stderr,"Line %i: %s\n", yylineno, error_text); exit(2); } -int main(int argc, char **argv) { +int main(int argc, char **argv) +{ + #if 0 + yydebug=1; + #endif yyparse(); return 0; } diff --git a/ag/scanner.lex b/ag/scanner.lex index f66b947..049cdd2 100644 --- a/ag/scanner.lex +++ b/ag/scanner.lex @@ -3,65 +3,57 @@ #include #include "parser.h" -KEYWORD func|end|struct|var|if|then|else|while|do|return|or|not -IDENTIFIER [[:alpha:]_][[:alnum:]_]* -NUMBER_HEX [0-9][0-9A-Fa-f]*H -NUMBER_DEC [0-9]+ -WHITESPACE [\t\n\r ] -COMMENT_START \(\* -COMMENT_END \*\) +KEYWORD struct|end|method|var|if|then|else|while|do|return|not|or|this +SPECIAL_CHAR \;|\(|\)|\:=|\.|\-|\*|\<|\=|\, +IDENTIFIER [a-zA-Z_][0-9a-zA-Z_]* +NUMBER_HEX 0x[0-9A-Fa-f]+ +NUMBER_DEC [0-9]+ +WHITESPACE [\t\n\r ] +COMMENT_START \/\* +COMMENT_END \*\/ %x COMMENT %option yylineno %% +{COMMENT_START} BEGIN(COMMENT); -{COMMENT_START} BEGIN(COMMENT); +{COMMENT_END} BEGIN(INITIAL); -{COMMENT_END} BEGIN(INITIAL); +<> { + fprintf(stderr, "Kommentar nicht geschlossen\n"); + exit(1); +} -{COMMENT_START} fprintf(stderr, "Possibly nested comment on line %i\n", yylineno); +(.|\n) /* alles im kommentar wird ignoriert */ -<> { fprintf(stderr, "Unterminated comment.\n"); exit(1); } +struct return(STRUCT); +end return(END); +method return(METHOD); +var return(VAR); +if return(IF); +then return(THEN); +else return(ELSE); +while return(WHILE); +do return(DO); +return return(RETURN); +not return(NOT); +or return(OR); +this return(THIS); -{WHITESPACE} /* ignore */ +{IDENTIFIER} return(IDENT); -. /* ignore everything inside comment */ +{NUMBER_DEC} return(NUM); +{NUMBER_HEX} return(NUM); -func return(FUNC); -end return(END); -struct return(STRUCT); -var return(VAR); -if return(IF); -then return(THEN); -else return(ELSE); -while return(WHILE); -do return(DO); -return return(RETURN); -or return(OR); -not return(NOT); +{SPECIAL_CHAR} return(*yytext); -{IDENTIFIER} return(ID); @{ @ID.name@=strdup(yytext); @} +{WHITESPACE} /* ignore */ -{NUMBER_DEC} return(NUM); -{NUMBER_HEX} return(NUM); - -\:= return(ASSIGN); ->= return(GREATER); -\; return(';'); -\. return('.'); -\( return('('); -\) return(')'); -\, return(','); -\- return('-'); -\+ return('+'); -\* return('*'); -= return('='); - -{WHITESPACE} /* ignore */ - -. { fprintf(stderr, "Lexical error on line %i\n", yylineno); exit(1); } +. { + fprintf(stderr, "Lexical error on line %i\n", yylineno); + exit(1); +} %% - -- 2.25.1