diff options
| Commit | 864e98585b287d68c1f8863850124adfdba7a5b8 (patch) | |
|---|---|---|
| Author | 2023-11-11 12:03:07 +0200 | |
| Committer | 2023-11-11 12:03:07 +0200 | |
| Files | 47129acddda964135e9b67c9d291093a7b1d05f9 | |
| uni-projects-864e98585b287d68c1f8863850124adfdba7a5b8.tar uni-projects-864e98585b287d68c1f8863850124adfdba7a5b8.tar.gz uni-projects-864e98585b287d68c1f8863850124adfdba7a5b8.zip | ||
| Parent | 822201b02fd5bd914d083d62bc095b47ff77ab21 (diff) | |
[CI/PA2] Implemented fully grammar
1 files changed, 155 insertions, 61 deletions
| -rw-r--r-- | Year 3/Compilers, Introduction/coolc-spim/my-code/coursework/pa2/cool.y | 216 |
diff --git a/Year 3/Compilers, Introduction/coolc-spim/my-code/coursework/pa2/cool.y b/Year 3/Compilers, Introduction/coolc-spim/my-code/coursework/pa2/cool.y index 74ab0d6..c5a4d7a 100644 --- a/Year 3/Compilers, Introduction/coolc-spim/my-code/coursework/pa2/cool.y +++ b/Year 3/Compilers, Introduction/coolc-spim/my-code/coursework/pa2/cool.y @@ -51,7 +51,7 @@ // Set the line number of the current non-terminal: // *********************************************** // You can access the line numbers of the i'th item with @i, just - // like you acess the value of the i'th exporession with $i. + // like you acess the value of the i'th expression with $i. // // Here, we choose the line number of the last INT_CONST (@3) as the // line number of the resulting expression (@$). You are free to pick @@ -74,7 +74,7 @@ - void yyerror(char *s); /* defined below; called for each parse error */ + void yyerror(const char *s); /* defined below; called for each parse error */ extern int yylex(); /* the entry point to the lexer */ /************************************************************************/ @@ -84,7 +84,7 @@ Classes parse_results; /* for use in semantic analysis */ int omerrs = 0; /* number of errors in lexing and parsing */ %} - + /* A union of all the types that can be the result of parsing actions. */ %union { Boolean boolean; @@ -124,106 +124,200 @@ /* DON'T CHANGE ANYTHING ABOVE THIS LINE, OR YOUR PARSER WONT WORK */ /**************************************************************************/ + + /* %define parse.error detailed */ /* Complete the nonterminal list below, giving a type for the semantic value of each non terminal. (See section 3.6 in the bison documentation for details). */ + /* Declare types for the grammar's non-terminals. */ %type <program> program - %type <classes> class_list %type <class_> class - - /* You will want to change the following line. */ - %type <features> dummy_feature_list + %type <classes> class_list + %type <feature> feature attribute method + %type <features> feature_list feature_list_nonempty + %type <formal> formal + %type <formals> formal_list formal_list_nonempty + %type <expression> expression dispatch static_dispatch let lets math_expression bool_expression + %type <expressions> expression_list expression_list_nonempty expression_block + %type <case_> case_ + %type <cases> case_list + /* Boolean boolean; */ + /* Symbol symbol; */ /* Precedence declarations go here. */ - %% program: class_list { @$ = @1; ast_root = program($1); } ; - class_list: class { $$ = single_Classes($1); parse_results = $$; } /* single class */ - | class_list class { $$ = append_Classes($1,single_Classes($2)); parse_results = $$; } /* several classes */ + // [[class;]]+ + class_list: class ';' { $$ = single_Classes($1); parse_results = $$; } + | class_list class ';' { $$ = append_Classes($1, single_Classes($2)); parse_results = $$; } ; - /* If no parent is specified, the class inherits from the Object class. */ - class: CLASS TYPEID '{' feature_list '}' ';' { $$ = class_($2,idtable.add_string("Object"),$4, stringtable.add_string(curr_filename)); } - | CLASS TYPEID INHERITS TYPEID '{' feature_list '}' ';' { $$ = class_($2,$4,$6,stringtable.add_string(curr_filename)); } + // class TYPE [inherits TYPE] { [[feature;]]* } + class: CLASS TYPEID '{' feature_list '}' { $$ = class_($2, idtable.add_string("Object"), $4, stringtable.add_string(curr_filename)); } + | CLASS TYPEID INHERITS TYPEID '{' feature_list '}' { $$ = class_($2, $4, $6, stringtable.add_string(curr_filename)); } ; - feature_list: feature - | feature ';' feature_list + // [[feature;]]* + feature_list: { $$ = nil_Features(); } + | feature_list_nonempty { $$ = $1; } ; - feature: attribute - | method + feature_list_nonempty: feature ';' { $$ = single_Features($1); } + | feature_list feature ';' { $$ = append_Features($1, single_Features($2)); } + ; + + // ID([formal [[, formal]]*]): TYPE { expr } + // | ID : TYPE [ <- expr ] + feature: method { $$ = $1; } + | attribute { $$ = $1; } ; - attribute: OBJECTID ':' TYPEID - | OBJECTID ':' TYPEID ASSIGN expression ';' + // ID : TYPE [ <- expr ] + attribute: OBJECTID ':' TYPEID { $$ = attr($1, $3, no_expr()); } + | OBJECTID ':' TYPEID ASSIGN expression { $$ = attr($1, $3, $5); } ; - method: OBJECTID '(' method_attr ')' ':' TYPEID '{' expression '}' ';' + // ID([formal [[, formal]]*]): TYPE { expr } + method: OBJECTID '(' formal_list ')' ':' TYPEID '{' expression '}' { $$ = method($1, $3, $6, $8); } ; - method_attr: OBJECTID ':' TYPEID - | OBJECTID ':' TYPEID ',' method_attr + // [formal [[, formal]]*] + formal_list: { $$ = nil_Formals(); } + | formal_list_nonempty { $$ = $1; } ; - expression: BOOL_CONST - | INT_CONST - | STR_CONST - | OBJECTID - | OBJECTID ASSIGN expression - | expression '.' OBJECTID '(' expression_list ')' - | OBJECTID '.' '(' expression_list ')' - | expression '@' TYPEID '.' 'i' 'd' '(' expression_list ')' - | IF expression THEN expression ELSE expression FI - | WHILE expression LOOP expression POOL - | expression_block - | LET OBJECTID ':' TYPED - | CASE expression OF expression_cases ESAC - | NEW TYPEID - | ISVOID expression - | expression operator expression - | NOT expression + // formal [[, formal]]* + formal_list_nonempty: formal { $$ = single_Formals($1); } + | formal_list ',' formal { $$ = append_Formals($1, single_Formals($3)); } + ; + + // ID : TYPE + formal: OBJECTID ':' TYPEID { $$ = formal($1, $3); } + + // ID <- expr + expression: OBJECTID ASSIGN expression { $$ = assign($1, $3); } + // expr[@TYPE].ID([expr [[,expr]]*]) + // | ID( [ expr [[, expr]]∗ ] ) + | static_dispatch { $$ = $1; } + | dispatch { $$ = $1; } + // if expr then expr else expr fi + | IF expression THEN expression ELSE expression FI { $$ = cond($2, $4, $6); } + // while expr loop expr pool + | WHILE expression LOOP expression POOL { $$ = loop($2, $4); } + // { [[expr;]]+ } + | '{' expression_block '}' { $$ = block($2); } + // let ID : TYPE [<- expr] [[, ID : TYPE [<- expr]]]* in expr + | let + // case expr of [[ID : TYPE => expr;]]+ esac + | CASE expression OF case_list ESAC { $$ = typcase($2, $4); } + // new TYPE + | NEW TYPEID { $$ = new_($2); } + // isvoid expr + | ISVOID expression { $$ = isvoid($2); } + // expr + expr + // | expr - expr + // | expr * expr + // | expr / expr + | math_expression + // ~ expr + // | expr < expr + // | expr <= expr + // | expr = expr + | bool_expression + // not expr + | NOT expression { $$ = comp($2); } + // (expr) + | '(' expression ')' { $$ = $2; } + // ID + | OBJECTID { $$ = object($1); } + // integer + | INT_CONST { $$ = int_const($1); } + // string + | STR_CONST { $$ = string_const($1); } + // true + // | false + | BOOL_CONST { $$ = bool_const($1); } ; - expression_list: expression - | expression ',' expression_list + // expr.ID([expr [[, expr]]*]) + // | ID([expr [[, expr]]*]) + dispatch: expression '.' OBJECTID '(' expression_list ')' { $$ = dispatch($1, $3, $5); } + | OBJECTID '(' expression_list ')' { $$ = dispatch(object(idtable.add_string("self")), $1, $3); } + + // expr@TYPE.ID([expr [[,expr]]*]) + static_dispatch: expression '@' TYPEID '.' OBJECTID '(' expression_list ')' { $$ = static_dispatch($1, $3, $5, $7); } ; - expression_block: expression - | expression ';' expression_block - ; + // [expr [[,expr]]*] + expression_list: { $$ = nil_Expressions(); } + | expression_list_nonempty { $$ = $1; } + ; - expression_cases: - | OBJECTID ':' TYPEID DARROW expression ';' expression_cases + // expr [[,expr]]* + expression_list_nonempty: expression { $$ = single_Expressions($1); } + | expression_list ',' expression { $$ = append_Expressions($1, single_Expressions($3)); } + ; + + // [[expr;]]+ + expression_block: expression ';' { $$ = single_Expressions($1); } + | expression_block expression ';' { $$ = append_Expressions($1, single_Expressions($2)); } ; - operator: '+' - | '-' - | '*' - | '/' - | '<' - | '<' '=' - | '=' - ; + // let ID : TYPE [<- expr] [[, ID : TYPE [<- expr]]]* in expr + // Special handling, since "let A:B, C:D in x" has to be transformed into "let A:B in let C:D in x" + let: LET OBJECTID ':' TYPEID IN expression { $$ = let($2, $4, no_expr(), $6); } + | LET OBJECTID ':' TYPEID ASSIGN expression IN expression { $$ = let($2, $4, $6, $8); } + | LET OBJECTID ':' TYPEID lets { $$ = let($2, $4, no_expr(), $5); } + | LET OBJECTID ':' TYPEID ASSIGN expression lets { $$ = let($2, $4, $6, $7); } + ; + + lets: ',' OBJECTID ':' TYPEID lets { $$ = let($2, $4, no_expr(), $5); } + | ',' OBJECTID ':' TYPEID ASSIGN expression lets { $$ = let($2, $4, $6, $7); } + | ',' OBJECTID ':' TYPEID IN expression { $$ = let($2, $4, no_expr(), $6); } + | ',' OBJECTID ':' TYPEID ASSIGN expression IN expression { $$ = let($2, $4, $6, $8); } + ; + + // [[ID : TYPE => expr;]]+ + case_list: case_ { $$ = single_Cases($1); } + | case_list case_ { $$ = append_Cases($1, single_Cases($2)); } + ; + + // ID : TYPE => expr; + case_: OBJECTID ':' TYPEID DARROW expression ';' { $$ = branch($1, $3, $5); } + ; + + // expr + expr + // | expr - expr + // | expr * expr + // | expr / expr + math_expression: expression '+' expression { $$ = plus($1, $3); } + | expression '-' expression { $$ = sub($1, $3); } + | expression '*' expression { $$ = mul($1, $3); } + | expression '/' expression { $$ = divide($1, $3); } + ; + + // ~ expr + // | expr < expr + // | expr <= expr + // | expr = expr + bool_expression: '~' expression { $$ = neg($2); } + | expression '<' expression { $$ = lt($1, $3); } + | expression LE expression { $$ = leq($1, $3); } + | expression '=' expression { $$ = eq($1, $3); } + ; - - /* Feature list may be empty, but no empty features in list. */ - dummy_feature_list: { $$ = nil_Features(); } /* empty */ - ; - - /* end of grammar */ %% /* This function is called automatically when Bison detects a parse error. */ - void yyerror(char *s) + void yyerror(const char *s) { extern int curr_lineno; |
