Summary Files Commits Branches @commit @diff @stats
diff options
context:
space:
mode:
Commit864e98585b287d68c1f8863850124adfdba7a5b8 (patch)
Author
 Syndamia <kamen@syndamia.com>
2023-11-11 12:03:07 +0200
Committer
 Syndamia <kamen@syndamia.com>
2023-11-11 12:03:07 +0200
Files47129acddda964135e9b67c9d291093a7b1d05f9
uni-projects-864e98585b287d68c1f8863850124adfdba7a5b8.tar
uni-projects-864e98585b287d68c1f8863850124adfdba7a5b8.tar.gz
uni-projects-864e98585b287d68c1f8863850124adfdba7a5b8.zip
Parent822201b02fd5bd914d083d62bc095b47ff77ab21 (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.y216
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;