From 13c7edfa3b3f4323aedaac1cf9f981d4db5adf99 Mon Sep 17 00:00:00 2001 From: Fredrik Robertsen Date: Sat, 14 Feb 2026 18:35:38 +0100 Subject: [PATCH] ps2/3: finish parser.y grammar --- ps2/src/parser.y | 185 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 170 insertions(+), 15 deletions(-) diff --git a/ps2/src/parser.y b/ps2/src/parser.y index 4ff9255..f84f3e4 100644 --- a/ps2/src/parser.y +++ b/ps2/src/parser.y @@ -40,8 +40,8 @@ program : global_list { root = $1; } ; global_list : - global { $$ = node_create(LIST, 1, $1); } - | global_list global { $$ = append_to_list_node($1, $2); } + global { $$ = node_create(LIST, 1, $1); } + | global_list global { $$ = append_to_list_node($1, $2); } ; global : global_variable_declaration { $$ = $1; } @@ -50,12 +50,165 @@ global_variable_declaration : VAR global_variable_list { $$ = node_create(GLOBAL_VARIABLE_DECLARATION, 1, $2); } ; global_variable_list : - global_variable { $$ = node_create(LIST, 1, $1); } - | global_variable_list ',' global_variable { $$ = append_to_list_node($1, $3); } + global_variable { $$ = node_create(LIST, 1, $1); } + | global_variable_list ',' global_variable { $$ = append_to_list_node($1, $3); } ; global_variable : identifier { $$ = $1; } ; +array_indexing : + identifier '[' expression ']' { $$ = node_create(ARRAY_INDEXING, 2, $1, $3); } + ; +parameter_list : + identifier { $$ = node_create(LIST, 1, $1); } + | parameter_list ',' identifier { $$ = append_to_list_node($1, $3); } + | { $$ = node_create(LIST, 0); } + ; +function : + FUNC identifier '(' parameter_list ')' statement { $$ = node_create(FUNCTION, 3, $2, $4, $6); } + ; +statement : + block { $$ = $1; } + | assignment_statement { $$ = $1; } + | return_statement { $$ = $1; } + | print_statement { $$ = $1; } + | println_statement { $$ = $1; } + | if_statement { $$ = $1; } + | while_statement { $$ = $1; } + | break_statement { $$ = $1; } + | function_call { $$ = $1; } + ; +block : + '{' statement_or_declaration_list '}' { $$ = node_create(BLOCK, 1, $2); } + ; +statement_or_declaration_list : + statement_or_declaration_list statement_or_declaration { $$ = append_to_list_node($1, $2); } + | { $$ = node_create(LIST, 0); } + ; +statement_or_declaration : + statement { $$ = $1; } + | local_variable_declaration { $$ = $1; } + ; +local_variable_declaration : + VAR local_variable_list { $$ = node_create(LOCAL_VARIABLE_DECLARATION, 1, $2); } + ; +local_variable_list : + local_variable { $$ = node_create(LIST, 1, $1); } + | local_variable_list ',' local_variable { $$ = append_to_list_node($1, $3); } + ; +local_variable : + identifier { $$ = node_create(LOCAL_VARIABLE, 1, $1); } + | identifier '=' expression { $$ = node_create(LOCAL_VARIABLE, 2, $1, $3); } + ; +assignment_statement : + identifier '=' expression { $$ = node_create(ASSIGNMENT_STATEMENT, 2, $1, $3); } + | array_indexing '=' expression { $$ = node_create(ASSIGNMENT_STATEMENT, 2, $1, $3); } + ; +return_statement : + RETURN expression { $$ = node_create(RETURN_STATEMENT, 1, $2); } + ; +print_statement : + PRINT '(' print_list ')' { $$ = node_create(PRINT_STATEMENT, 1, $3); } + ; +println_statement : + PRINTLN '(' print_list ')' { $$ = node_create(PRINTLN_STATEMENT, 1, $3); } + ; +print_list : + print_item { $$ = node_create(LIST, 1, $1); } + | print_list ',' print_item { $$ = append_to_list_node($1, $3); } + ; +print_item : + expression { $$ = $1; } + | string { $$ = $1; } + ; +break_statement : + BREAK { $$ = node_create(BREAK_STATEMENT, 0); } + ; +if_statement : + IF '(' expression ')' statement { $$ = node_create(IF_STATEMENT, 2, $3, $5); } + | IF '(' expression ')' statement ELSE statement { $$ = node_create(IF_STATEMENT, 3, $3, $5, $7); } + ; +while_statement : + WHILE '(' expression ')' statement { $$ = node_create(WHILE_STATEMENT, 2, $3, $5); } + ; +expression : + expression '?' expression ':' expression { + $$ = node_create(OPERATOR, 3, $1, $2, $3); + $$->data.operator = "?:"; + } + | expression OR expression { + $$ = node_create(OPERATOR, 2, $1, $3); + $$->data.operator = "or"; + } + | expression AND expression { + $$ = node_create(OPERATOR, 2, $1, $3); + $$->data.operator = "and"; + } + | expression '=' '=' expression { + $$ = node_create(OPERATOR, 2, $1, $4); + $$->data.operator = "=="; + } + | expression '!' '=' expression { + $$ = node_create(OPERATOR, 2, $1, $4); + $$->data.operator = "!="; + } + | expression '<' expression { + $$ = node_create(OPERATOR, 2, $1, $3); + $$->data.operator = "<"; + } + | expression '<' '=' expression { + $$ = node_create(OPERATOR, 2, $1, $4); + $$->data.operator = "<="; + } + | expression '>' expression { + $$ = node_create(OPERATOR, 2, $1, $3); + $$->data.operator = ">"; + } + | expression '>' '=' expression { + $$ = node_create(OPERATOR, 2, $1, $4); + $$->data.operator = ">="; + } + | expression '+' expression { + $$ = node_create(OPERATOR, 2, $1, $3); + $$->data.operator = "+"; + } + | expression '-' expression { + $$ = node_create(OPERATOR, 2, $1, $3); + $$->data.operator = "-"; + } + | expression '*' expression { + $$ = node_create(OPERATOR, 2, $1, $3); + $$->data.operator = "*"; + } + | expression '/' expression { + $$ = node_create(OPERATOR, 2, $1, $3); + $$->data.operator = "/"; + } + | '-' expression { + $$ = node_create(OPERATOR, 1, $2); + $$->data.operator = "-"; + } %prec UNARY_OPERATORS + | '!' expression { + $$ = node_create(OPERATOR, 1, $2); + $$->data.operator = "!"; + } %prec UNARY_OPERATORS + | '(' expression ')' { $$ = $1; } + | number { $$ = $1; } + | identifier { $$ = $1; } + | array_indexing { $$ = $1; } + | function_call { $$ = $1; } + ; +function_call : + identifier '(' argument_list ')' { $$ = node_create(FUNCTION_CALL, 2, $1, $3); } + ; +argument_list : + expression_list { $$ = $1; } + | { $$ = node_create(LIST, 0); } + ; +expression_list : + expression { $$ = node_create(LIST, 1, $1); } + | expression_list ',' expression { $$ = append_to_list_node($1, $3); } + ; identifier : IDENTIFIER_TOKEN { @@ -64,15 +217,17 @@ identifier : // Allocate a copy of yytext to keep in the syntax tree as data $$->data.identifier = strdup(yytext); } - -/* - * This file can currently only recognize global variable declarations, i.e, - * - * var myVar, anotherVar, third - * var theLastOne - * - * TODO: - * Include the remaining modified VSL grammar as specified in the task description. - * This should be a pretty long file when you are done. - */ + ; +number : + NUMBER_TOKEN { + $$ = node_create(NUMBER_LITERAL, 0); + $$->data.number_literal = strtol(yytext, &yytext[0] + strlen(yytext), 10); + } + ; +string : + STRING_TOKEN { + $$ = node_create(STRING_LITERAL, 0); + $$->data.string_literal = strdup(yytext); + } + ; %%