first compilation pass

This commit is contained in:
ridethepig 2023-03-22 20:44:13 +08:00
parent 4db0884baa
commit 1d3822faef

View File

@ -159,10 +159,11 @@
%nonassoc '<' LE '=' %nonassoc '<' LE '='
%left '+' '-' %left '+' '-'
%left '*' '/' %left '*' '/'
%precedence ISVOID %nonassoc ISVOID
%precedence '~' %nonassoc '~'
%precedence '@' %nonassoc '@'
%precedence '.' %nonassoc '.'
%left LETEXPR
%% %%
@ -188,15 +189,15 @@
stringtable.add_string(curr_filename)); } stringtable.add_string(curr_filename)); }
| CLASS TYPEID INHERITS TYPEID '{' feature_list '}' ';' | CLASS TYPEID INHERITS TYPEID '{' feature_list '}' ';'
{ $$ = class_($2,$4,$6,stringtable.add_string(curr_filename)); } { $$ = class_($2,$4,$6,stringtable.add_string(curr_filename)); }
| CLASS TYPEID INHERITS TYPEID '{' '}' ';'
{ $$ = class_($2,$4,nil_Features(),stringtable.add_string(curr_filename)); }
; ;
/* Feature list may be empty, but no empty features in list. */ /* Feature list may be empty, but no empty features in list. */
feature_list: /* empty */ feature_list : feature ';'
{ $$ = nil_Features(); }
| feature ';'
{ $$ = single_Features($1); } { $$ = single_Features($1); }
| feature_list feature ';' | feature_list feature ';'
{ $$ = append_Classes($1, single_Features($2)); } { $$ = append_Features($1, single_Features($2)); }
; ;
feature : OBJECTID ':' TYPEID feature : OBJECTID ':' TYPEID
@ -206,11 +207,12 @@
{ $$ = attr($1, $3, $5); } { $$ = attr($1, $3, $5); }
| OBJECTID '(' formal_list ')' ':' TYPEID '{' expression '}' | OBJECTID '(' formal_list ')' ':' TYPEID '{' expression '}'
{ $$ = method($1, $3, $6, $8); } { $$ = method($1, $3, $6, $8); }
| OBJECTID '(' ')' ':' TYPEID '{' expression '}'
{ $$ = method($1, nil_Formals(), $5, $7); }
; ;
formal_list : /* empty */ formal_list
{ $$ = nil_Formals(); } : formal
| formal
{ $$ = single_Formals($1); } { $$ = single_Formals($1); }
| formal_list ',' formal /* a little different from classlist */ | formal_list ',' formal /* a little different from classlist */
{ $$ = append_Formals($1, single_Formals($3)); } { $$ = append_Formals($1, single_Formals($3)); }
@ -220,17 +222,15 @@
{ $$ = formal($1, $3); } { $$ = formal($1, $3); }
; ;
expression_list_comma : /* TODO Perhaps empty expr_list should not be valid? */ expression_list_comma
{ $$ = nil_Expressions(); } : expression
| expression
{ $$ = single_Expressions($1); } { $$ = single_Expressions($1); }
| expression_list_comma ',' expression | expression_list_comma ',' expression
{ $$ = append_Expressions($1, single_Expressions($3)); } { $$ = append_Expressions($1, single_Expressions($3)); }
; ;
expression_list_colon : /* TODO Perhaps empty expr_list should not be valid? */ expression_list_colon
{ $$ = nil_Expressions(); } : expression ';' /* the only usage `{ [[expr; ]]+}` says one or more exprs needed, so no empty option*/
| expression ';'
{ $$ = single_Expressions($1); } { $$ = single_Expressions($1); }
| expression_list_colon expression ';' | expression_list_colon expression ';'
{ $$ = append_Expressions($1, single_Expressions($2)); } { $$ = append_Expressions($1, single_Expressions($2)); }
@ -241,23 +241,36 @@
/* expr[@TYPE].ID([expr[[,expr]]*]) */ /* expr[@TYPE].ID([expr[[,expr]]*]) */
| expression '.' OBJECTID '(' expression_list_comma ')' | expression '.' OBJECTID '(' expression_list_comma ')'
{ $$ = dispatch($1, $3, $5); } { $$ = dispatch($1, $3, $5); }
| expression '.' OBJECTID '(' ')'
{ $$ = dispatch($1, $3, nil_Expressions()); }
/* Only in the case of @TYPE, we use static dispatch*/ /* Only in the case of @TYPE, we use static dispatch*/
| expression '@' TYPEID '.' OBJECTID '(' expression_list_comma ')' | expression '@' TYPEID '.' OBJECTID '(' expression_list_comma ')'
{ $$ = static_dispatch($1, $3, $5, $7); } { $$ = static_dispatch($1, $3, $5, $7); }
| expression '@' TYPEID '.' OBJECTID '(' ')'
{ $$ = static_dispatch($1, $3, $5, nil_Expressions()); }
/* Actually, `ID( [ expr [[, expr]] ])` is self omitted, so add it in parsing */ /* Actually, `ID( [ expr [[, expr]] ])` is self omitted, so add it in parsing */
| OBJECTID '(' expression_list_comma ')' | OBJECTID '(' expression_list_comma ')'
{ $$ = dispatch(object(idtable.add_string("self")), $1, $3); } { $$ = dispatch(object(idtable.add_string("self")), $1, $3); }
| OBJECTID '(' ')'
{ $$ = dispatch(object(idtable.add_string("self")), $1, nil_Expressions()); }
| IF expression THEN expression ELSE expression FI | IF expression THEN expression ELSE expression FI
{ $$ = cond($2, $4, $6); } { $$ = cond($2, $4, $6); }
| WHILE expression LOOP expression POOL | WHILE expression LOOP expression POOL
{ $$ = loop($2, $4); } { $$ = loop($2, $4); }
| '{' expression_list_colon '}' | '{' expression_list_colon '}'
{ $$ = block($2); } { $$ = block($2); }
/* TODO let expr */
/* [manual-P21, tour-section6.5] /* [manual-P21, tour-section6.5]
* The let constructor only allows one identifier. * The let constructor only allows one identifier.
* When parsing a let with multiple idents, it should be transformed into nested lets * When parsing a let with multiple idents, it should be transformed into nested lets
*/ */
/* It is not any obvious to me where the shift-reduce conflict lies.
* Try `bison -Wcounterexample {OTHERFLAGS} cool.y > counterexample.txt 2>&1`
* Thanks to the examples, one possible situation could be: let id1:T1 in expression.f()
* there could be 2 interpretations: (let id1:T1 in expression).f() | let id1:T1 in (expression.f())
* This should be specified to dis-ambiguite
*
* The manual says, the expr extends as far as possible
*/
| LET nested_let | LET nested_let
{ $$ = $2; } { $$ = $2; }
| CASE expression OF case_list ESAC | CASE expression OF case_list ESAC
@ -265,7 +278,7 @@
| NEW TYPEID | NEW TYPEID
{ $$ = new_($2); } { $$ = new_($2); }
| ISVOID expression | ISVOID expression
{ $$ = isvoid($1); } { $$ = isvoid($2); }
/* the rules below need precedence specification */ /* the rules below need precedence specification */
| expression '+' expression | expression '+' expression
{ $$ = plus($1, $3); } { $$ = plus($1, $3); }
@ -276,7 +289,7 @@
| expression '/' expression | expression '/' expression
{ $$ = divide($1, $3); } { $$ = divide($1, $3); }
| '~' expression | '~' expression
{ $$ = beg($2); } { $$ = neg($2); }
| expression '<' expression | expression '<' expression
{ $$ = lt($1, $3); } { $$ = lt($1, $3); }
| expression LE expression | expression LE expression
@ -300,21 +313,23 @@
case_list : case ';' case_list : case ';'
{ $$ = single_Cases($1); } { $$ = single_Cases($1); }
| case_list case ';' | case_list case ';'
{ $$ = append_Casess($1, single_Cases($2)); } { $$ = append_Cases($1, single_Cases($2)); }
; ;
case : OBJECTID ':' TYPEID DARROW expression case : OBJECTID ':' TYPEID DARROW expression
{ $$ = branch($1, $3, $5); } { $$ = branch($1, $3, $5); }
; ;
nested_let: OBJECTID ':' TYPEID ',' nested_let nested_let
: OBJECTID ':' TYPEID ',' nested_let
{ $$ = let($1, $3, no_expr(), $5); } { $$ = let($1, $3, no_expr(), $5); }
| OBJECTID ':' TYPEID ASSIGN expression ',' nested_let | OBJECTID ':' TYPEID ASSIGN expression ',' nested_let
{ $$ = let($1, $3, $5, $7); } { $$ = let($1, $3, $5, $7); }
| nested_let OBJECTID ':' TYPEID IN expression | OBJECTID ':' TYPEID IN expression %prec LETEXPR
{ $$ = let($2, $4, no_expr(), $6); } { $$ = let($1, $3, no_expr(), $5); }
| nested_let OBJECTID ':' TYPEID ASSIGN expression IN expression | OBJECTID ':' TYPEID ASSIGN expression IN expression %prec LETEXPR
{ $$ = let($2, $4, $6, $8); } { $$ = let($1, $3, $5, $7); }
;
/* end of grammar */ /* end of grammar */
%% %%