From d0646c2652516bf203361b166aef925a00662ec4 Mon Sep 17 00:00:00 2001 From: Dayanne Fernandes Date: Fri, 30 Oct 2020 00:13:22 -0300 Subject: [PATCH 01/10] init symbol table print --- src/core/ast.c | 2 +- src/core/ast.h | 6 +++--- src/core/main.c | 6 +++++- src/core/sym_tab.c | 33 +++++++++++++++++++++++++-------- src/core/sym_tab.h | 12 +++++++----- src/tests/parser/valid_1.ppy | 2 +- 6 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/core/ast.c b/src/core/ast.c index c5f174c..b0b6989 100644 --- a/src/core/ast.c +++ b/src/core/ast.c @@ -2,7 +2,7 @@ #include #include "ast.h" -ast_node* create_bin_expr(char *operator, ast_node* left, ast_node* right) { +ast_node* create_bin_expr(char* operator, ast_node* left, ast_node* right) { if (PARSER_VERBOSE) printf("\nCreating binary expression node: .%d. .%s. .%d.\n", left->op.integer_expr, operator, right->op.integer_expr); ast_node* expr = (ast_node*) malloc(sizeof(ast_node)); diff --git a/src/core/ast.h b/src/core/ast.h index 9704ea8..95a90a8 100644 --- a/src/core/ast.h +++ b/src/core/ast.h @@ -14,9 +14,9 @@ typedef struct exp { int tag; union { int integer_expr; - char *variable_expr; + char* variable_expr; struct { - char *operator; + char* operator; struct exp* left; struct exp* right; } binary_expr; @@ -31,7 +31,7 @@ ast_node* print_exp(ast_node* node); void create_empy_ast(); void create_ast(ast_node* expression); ast_node* create_int_expr(int value); -ast_node* create_bin_expr(char *operator, ast_node* left, ast_node* right); +ast_node* create_bin_expr(char* operator, ast_node* left, ast_node* right); void handle_token(int token); diff --git a/src/core/main.c b/src/core/main.c index b4a5bc7..f87c625 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1,9 +1,10 @@ #include +#include "sym_tab.h" #include "ast.h" #include "lexer.h" #include "parser.h" -int main (int argc, char *argv[]) { +int main (int argc, char* argv[]) { printf("Welcome to CPPython interpreter:\n"); MAIN_VERBOSE = LEX_VERBOSE = PARSER_VERBOSE = AST_LVL = 0; root = NULL; @@ -21,6 +22,9 @@ int main (int argc, char *argv[]) { printf("Abstract Syntax Tree:\n"); print_ast(root); + + printf("\nSymbol Table:\n"); + print_st(); return 0; } diff --git a/src/core/sym_tab.c b/src/core/sym_tab.c index 546bd66..ea6b37c 100644 --- a/src/core/sym_tab.c +++ b/src/core/sym_tab.c @@ -1,33 +1,50 @@ +#include #include "sym_tab.h" -void add_word(int key, char *name) { - struct word *s; +void add_word(int key, char* name) { + word* s; HASH_FIND_INT(symbol_table, &key, s); if (s == NULL) { - s = (struct word *) malloc(sizeof *s); + s = (word*) malloc(sizeof(word)); s->key = key; HASH_ADD_INT(symbol_table, key, s); } strcpy(s->name, name); } -struct word *find_word(int word_key) { - struct word *s; - +word* find_word(int word_key) { + word* s; HASH_FIND_INT(symbol_table, &word_key, s); return s; } -void delete_word(struct word *s) { +void delete_word(word* s) { HASH_DEL(symbol_table, s); free(s); } void delete_all() { - struct word *cur_word, *tmp; + word* cur_word, *tmp; + HASH_ITER(hh, symbol_table, cur_word, tmp) { + HASH_DEL(symbol_table, cur_word); + free(cur_word); + } +} + +void print_st() { + unsigned int num_symbols = HASH_COUNT(symbol_table); + + if (num_symbols == 0) { + printf("Empty symbol table.\n"); + return; + } + + printf("Size: %u\n", num_symbols); + word* cur_word, *tmp; HASH_ITER(hh, symbol_table, cur_word, tmp) { + printf("KEY: %d, NAME: %s", cur_word->key, cur_word->name); HASH_DEL(symbol_table, cur_word); free(cur_word); } diff --git a/src/core/sym_tab.h b/src/core/sym_tab.h index 8e9422c..25cd8e0 100644 --- a/src/core/sym_tab.h +++ b/src/core/sym_tab.h @@ -3,17 +3,19 @@ #include "uthash.h" -struct word { +typedef struct word_pos { int key; char name[50]; UT_hash_handle hh; /* makes this structure hashable */ -}; +} word; -struct word *symbol_table; +word* symbol_table; + +void print_st(); void add_word(int key, char *name); -struct word *find_word(int word_key); -void delete_word(struct word *s); +word* find_word(int word_key); +void delete_word(word* s); void delete_all(); #endif // __SYM_TAB_H__ \ No newline at end of file diff --git a/src/tests/parser/valid_1.ppy b/src/tests/parser/valid_1.ppy index 8d2f097..0b4439e 100644 --- a/src/tests/parser/valid_1.ppy +++ b/src/tests/parser/valid_1.ppy @@ -1 +1 @@ -1 + 1 +1 - 1 From 6a7adec8b3092f0ed93d1f656bbf8bd5815f81f0 Mon Sep 17 00:00:00 2001 From: Dayanne Fernandes Date: Fri, 30 Oct 2020 00:14:49 -0300 Subject: [PATCH 02/10] fix mult and div op --- src/parser/cppython.y | 14 +++++++------- src/parser/parser.c | 8 ++++---- src/tests/parser/valid_1.ppy | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/parser/cppython.y b/src/parser/cppython.y index e78150a..9a197e1 100644 --- a/src/parser/cppython.y +++ b/src/parser/cppython.y @@ -32,17 +32,17 @@ input : /* empty */ { create_empy_ast(); } | expr { create_ast($1); } ; -expr : term[L] ADD[C] term[R] { $$ = create_bin_expr("+", $L, $R); } - | term[L] SUB[C] term[R] { $$ = create_bin_expr("-", $L, $R); } - | term[U] { $$ = print_exp($U); } +expr : term[L] ADD term[R] { $$ = create_bin_expr("+", $L, $R); } + | term[L] SUB term[R] { $$ = create_bin_expr("-", $L, $R); } + | term[U] { $$ = print_exp($U); } ; -term : factor[L] MULT[C] factor[R] { $$ = create_bin_expr($C, $L, $R); } - | factor[L] DIV[C] factor[R] { $$ = create_bin_expr($C, $L, $R); } - | factor[U] { $$ = print_exp($U); } +term : factor[L] MULT factor[R] { $$ = create_bin_expr("*", $L, $R); } + | factor[L] DIV factor[R] { $$ = create_bin_expr("/", $L, $R); } + | factor[U] { $$ = print_exp($U); } ; -factor : INTEGER[U] { $$ = create_int_expr($U); } +factor : INTEGER[U] { $$ = create_int_expr($U); } ; %% diff --git a/src/parser/parser.c b/src/parser/parser.c index 5e77df5..a6db8bc 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -1322,13 +1322,13 @@ yyparse (void) case 4: #line 35 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("+", (yyvsp[-2].expression), (yyvsp[0].expression)); } + { (yyval.expression) = create_bin_expr("+", (yyvsp[-2].expression), (yyvsp[0].expression)); } #line 1327 "parser/parser.c" break; case 5: #line 36 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("-", (yyvsp[-2].expression), (yyvsp[0].expression)); } + { (yyval.expression) = create_bin_expr("-", (yyvsp[-2].expression), (yyvsp[0].expression)); } #line 1333 "parser/parser.c" break; @@ -1340,13 +1340,13 @@ yyparse (void) case 7: #line 40 "parser/cppython.y" - { (yyval.expression) = create_bin_expr((yyvsp[-1].op), (yyvsp[-2].expression), (yyvsp[0].expression)); } + { (yyval.expression) = create_bin_expr("*", (yyvsp[-2].expression), (yyvsp[0].expression)); } #line 1345 "parser/parser.c" break; case 8: #line 41 "parser/cppython.y" - { (yyval.expression) = create_bin_expr((yyvsp[-1].op), (yyvsp[-2].expression), (yyvsp[0].expression)); } + { (yyval.expression) = create_bin_expr("/", (yyvsp[-2].expression), (yyvsp[0].expression)); } #line 1351 "parser/parser.c" break; diff --git a/src/tests/parser/valid_1.ppy b/src/tests/parser/valid_1.ppy index 0b4439e..645e6d9 100644 --- a/src/tests/parser/valid_1.ppy +++ b/src/tests/parser/valid_1.ppy @@ -1 +1 @@ -1 - 1 +1 / 1 From 35b675e7165b15b1349b075e8a1fa471d127bba1 Mon Sep 17 00:00:00 2001 From: Dayanne Fernandes Date: Fri, 30 Oct 2020 00:57:19 -0300 Subject: [PATCH 03/10] improve syntax and lexical error handlers --- src/core/ast.h | 2 +- src/core/main.c | 4 +- src/lexer/cppython.lex | 19 ++-- src/lexer/lexer.c | 112 +++++++++++++------ src/lexer/lexer.h | 2 +- src/parser/cppython.y | 19 +++- src/parser/parser.c | 155 +++++++++++++++----------- src/parser/parser.h | 7 +- src/parser/parser.output | 195 ++++++++++++++++++++------------- src/tests/parser/invalid_1.ppy | 3 +- 10 files changed, 322 insertions(+), 196 deletions(-) diff --git a/src/core/ast.h b/src/core/ast.h index 95a90a8..bba4d46 100644 --- a/src/core/ast.h +++ b/src/core/ast.h @@ -2,7 +2,7 @@ #define __AST_H__ int LEX_VERBOSE, PARSER_VERBOSE, MAIN_VERBOSE, AST_LVL; -int line, column; +int lex_line, lex_column, parser_line, parser_column; enum TAG { INTEGER_TYPE=0, diff --git a/src/core/main.c b/src/core/main.c index f87c625..86f0eb6 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -11,9 +11,9 @@ int main (int argc, char* argv[]) { // init lexer and parser printf("Lexer/parser:\n"); - line = column = 1; + lex_line = lex_column = parser_line = parser_column = 1; yyin = fopen(argv[1], "r"); - if (MAIN_VERBOSE) printf("\nline %d. ", line); + if (MAIN_VERBOSE) printf("\nline %d. ", lex_line); do { yyparse(); } while (!feof(yyin)); diff --git a/src/lexer/cppython.lex b/src/lexer/cppython.lex index a523393..03cb351 100644 --- a/src/lexer/cppython.lex +++ b/src/lexer/cppython.lex @@ -29,6 +29,7 @@ %option outfile="lexer/lexer.c" header-file="lexer/lexer.h" %option nounput %option noinput +%option yylineno /* regex and token definition */ @@ -80,7 +81,7 @@ NUMBER ({INTEGER}|{FLOAT}) /* general */ -{NEWLINE} { handle_token(NEWLINE_TOK); }; +{NEWLINE} { handle_token(NEWLINE_TOK); return NEWLINE; }; {WHITESPACE} ; {VAR} ; . { handle_token(ERROR_TOK); }; /* any character but newline */ @@ -94,6 +95,7 @@ NUMBER ({INTEGER}|{FLOAT}) */ void handle_token(int token) { + parser_column = lex_column; switch (token) { case INTEGER_TOK: if (LEX_VERBOSE) printf("Token: ", yytext); @@ -116,16 +118,17 @@ void handle_token(int token) { yylval.op = yytext; break; case NEWLINE_TOK: - line += 1; - column = 0; // reset column index - if (LEX_VERBOSE) printf("\nline %d. ", line); + parser_line = lex_line; + parser_column = lex_column; + lex_line += 1; + lex_column = 0; // reset column index + if (LEX_VERBOSE) printf("\nline %d. ", lex_line); break; case ERROR_TOK: - if (LEX_VERBOSE) printf("\nLexerError: line %d, column %d, token '%s' is not recognized\n", - line, column, yytext); - exit(1); + printf("\nLexError: token '%s' is not recognized in line %d, column %d.\n", + yytext, lex_line, lex_column); default: break; // ignore } - column += strlen(yytext); + lex_column += strlen(yytext); } \ No newline at end of file diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index 8f3632e..3a2fae9 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -163,8 +163,27 @@ extern FILE *yyin, *yyout; #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 - #define YY_LESS_LINENO(n) - #define YY_LINENO_REWIND_TO(ptr) + /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires + * access to the local variable yy_act. Since yyless() is a macro, it would break + * existing scanners that call yyless() from OUTSIDE yylex. + * One obvious solution it to make yy_act a global. I tried that, and saw + * a 5% performance hit in a non-yylineno scanner, because yy_act is + * normally declared as a register variable-- so it is not worth it. + */ + #define YY_LESS_LINENO(n) \ + do { \ + int yyl;\ + for ( yyl = n; yyl < yyleng; ++yyl )\ + if ( yytext[yyl] == '\n' )\ + --yylineno;\ + }while(0) + #define YY_LINENO_REWIND_TO(dst) \ + do {\ + const char *p;\ + for ( p = yy_cp-1; p >= (dst); --p)\ + if ( *p == '\n' )\ + --yylineno;\ + }while(0) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ @@ -486,6 +505,11 @@ static const flex_int16_t yy_chk[180] = 79, 79, 79, 79, 79, 79, 79, 79, 79 } ; +/* Table of booleans, true if rule could match eol. */ +static const flex_int32_t yy_rule_can_match_eol[18] = + { 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, }; + static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; @@ -526,11 +550,11 @@ char *yytext; MULT_TOK, DIV_TOK }; -#line 530 "lexer/lexer.c" +#line 554 "lexer/lexer.c" #define YY_NO_INPUT 1 -#line 34 "lexer/cppython.lex" +#line 35 "lexer/cppython.lex" /* regex and token definition */ -#line 534 "lexer/lexer.c" +#line 558 "lexer/lexer.c" #define INITIAL 0 @@ -745,12 +769,12 @@ YY_DECL } { -#line 56 "lexer/cppython.lex" +#line 57 "lexer/cppython.lex" /* reserved keywords */ -#line 754 "lexer/lexer.c" +#line 778 "lexer/lexer.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -796,6 +820,16 @@ YY_DECL YY_DO_BEFORE_ACTION; + if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) + { + int yyl; + for ( yyl = 0; yyl < yyleng; ++yyl ) + if ( yytext[yyl] == '\n' ) + + yylineno++; +; + } + do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) @@ -809,96 +843,96 @@ YY_DECL case 1: YY_RULE_SETUP -#line 60 "lexer/cppython.lex" +#line 61 "lexer/cppython.lex" ; YY_BREAK /* arithmetic expressions */ case 2: YY_RULE_SETUP -#line 64 "lexer/cppython.lex" +#line 65 "lexer/cppython.lex" { handle_token(INTEGER_TOK); return INTEGER; }; YY_BREAK case 3: YY_RULE_SETUP -#line 65 "lexer/cppython.lex" +#line 66 "lexer/cppython.lex" ; YY_BREAK case 4: YY_RULE_SETUP -#line 66 "lexer/cppython.lex" +#line 67 "lexer/cppython.lex" { handle_token(SUB_TOK); return SUB; }; YY_BREAK case 5: YY_RULE_SETUP -#line 67 "lexer/cppython.lex" +#line 68 "lexer/cppython.lex" { handle_token(ADD_TOK); return ADD; }; YY_BREAK case 6: YY_RULE_SETUP -#line 68 "lexer/cppython.lex" +#line 69 "lexer/cppython.lex" { handle_token(MULT_TOK); return MULT; }; YY_BREAK case 7: YY_RULE_SETUP -#line 69 "lexer/cppython.lex" +#line 70 "lexer/cppython.lex" { handle_token(DIV_TOK); return DIV; }; YY_BREAK case 8: YY_RULE_SETUP -#line 70 "lexer/cppython.lex" +#line 71 "lexer/cppython.lex" ; YY_BREAK /* conditional and booleans expressions */ case 9: YY_RULE_SETUP -#line 74 "lexer/cppython.lex" +#line 75 "lexer/cppython.lex" ; YY_BREAK case 10: YY_RULE_SETUP -#line 75 "lexer/cppython.lex" +#line 76 "lexer/cppython.lex" ; YY_BREAK /* structure helpers */ case 11: /* rule 11 can match eol */ YY_RULE_SETUP -#line 79 "lexer/cppython.lex" +#line 80 "lexer/cppython.lex" ; YY_BREAK case 12: YY_RULE_SETUP -#line 80 "lexer/cppython.lex" +#line 81 "lexer/cppython.lex" ; YY_BREAK /* general */ case 13: /* rule 13 can match eol */ YY_RULE_SETUP -#line 84 "lexer/cppython.lex" -{ handle_token(NEWLINE_TOK); }; +#line 85 "lexer/cppython.lex" +{ handle_token(NEWLINE_TOK); return NEWLINE; }; YY_BREAK case 14: YY_RULE_SETUP -#line 85 "lexer/cppython.lex" +#line 86 "lexer/cppython.lex" ; YY_BREAK case 15: YY_RULE_SETUP -#line 86 "lexer/cppython.lex" +#line 87 "lexer/cppython.lex" ; YY_BREAK case 16: YY_RULE_SETUP -#line 87 "lexer/cppython.lex" +#line 88 "lexer/cppython.lex" { handle_token(ERROR_TOK); }; /* any character but newline */ YY_BREAK case 17: YY_RULE_SETUP -#line 89 "lexer/cppython.lex" +#line 90 "lexer/cppython.lex" ECHO; YY_BREAK -#line 902 "lexer/lexer.c" +#line 936 "lexer/lexer.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -1306,6 +1340,11 @@ static int yy_get_next_buffer (void) *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); + if ( c == '\n' ) + + yylineno++; +; + return c; } #endif /* ifndef YY_NO_INPUT */ @@ -1772,6 +1811,9 @@ static int yy_init_globals (void) * This function is called from yylex_destroy(), so don't allocate here. */ + /* We do not touch yylineno unless the option is enabled. */ + yylineno = 1; + (yy_buffer_stack) = NULL; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; @@ -1866,7 +1908,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 89 "lexer/cppython.lex" +#line 90 "lexer/cppython.lex" /* @@ -1876,6 +1918,7 @@ void yyfree (void * ptr ) */ void handle_token(int token) { + parser_column = lex_column; switch (token) { case INTEGER_TOK: if (LEX_VERBOSE) printf("Token: ", yytext); @@ -1898,16 +1941,17 @@ void handle_token(int token) { yylval.op = yytext; break; case NEWLINE_TOK: - line += 1; - column = 0; // reset column index - if (LEX_VERBOSE) printf("\nline %d. ", line); + parser_line = lex_line; + parser_column = lex_column; + lex_line += 1; + lex_column = 0; // reset column index + if (LEX_VERBOSE) printf("\nline %d. ", lex_line); break; case ERROR_TOK: - if (LEX_VERBOSE) printf("\nLexerError: line %d, column %d, token '%s' is not recognized\n", - line, column, yytext); - exit(1); + printf("\nLexError: token '%s' is not recognized in line %d, column %d.\n", + yytext, lex_line, lex_column); default: break; // ignore } - column += strlen(yytext); + lex_column += strlen(yytext); } diff --git a/src/lexer/lexer.h b/src/lexer/lexer.h index c8d2c33..b6ee6dd 100644 --- a/src/lexer/lexer.h +++ b/src/lexer/lexer.h @@ -466,7 +466,7 @@ extern int yylex (void); #undef yyTABLES_NAME #endif -#line 89 "lexer/cppython.lex" +#line 90 "lexer/cppython.lex" #line 473 "lexer/lexer.h" diff --git a/src/parser/cppython.y b/src/parser/cppython.y index 9a197e1..04b31e8 100644 --- a/src/parser/cppython.y +++ b/src/parser/cppython.y @@ -1,13 +1,15 @@ %{ + #include #include #include "ast.h" int yylex(); - void yyerror(char *s); + void yyerror(const char *s); %} %output "parser/parser.c" %defines "parser/parser.h" +%define parse.error verbose %define lr.type ielr %start input @@ -20,6 +22,7 @@ %token ADD SUB MULT DIV %token INTEGER +%token NEWLINE %left ADD SUB %left MULT DIV @@ -28,8 +31,13 @@ %% -input : /* empty */ { create_empy_ast(); } - | expr { create_ast($1); } +input : /* empty */ { create_empy_ast(); } + | input line { create_empy_ast(); } + + +line : NEWLINE { create_empy_ast(); } + | expr NEWLINE { create_ast($1); } + | error NEWLINE { yyerrok; } ; expr : term[L] ADD term[R] { $$ = create_bin_expr("+", $L, $R); } @@ -47,6 +55,7 @@ factor : INTEGER[U] { $$ = create_int_expr($U); } %% -void yyerror(char *s) { - printf("%s\n", s); +void yyerror(const char *s) { + printf("\nSyntaxError: %s in line %d, column %d.\n", + s, parser_line, parser_column); } diff --git a/src/parser/parser.c b/src/parser/parser.c index a6db8bc..27742e6 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -68,13 +68,14 @@ /* First part of user prologue. */ #line 1 "parser/cppython.y" + #include #include #include "ast.h" int yylex(); - void yyerror(char *s); + void yyerror(const char *s); -#line 78 "parser/parser.c" +#line 79 "parser/parser.c" # ifndef YY_CAST # ifdef __cplusplus @@ -102,7 +103,7 @@ # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else -# define YYERROR_VERBOSE 0 +# define YYERROR_VERBOSE 1 #endif /* Use api.header.include to #include this header @@ -126,7 +127,8 @@ extern int yydebug; SUB = 259, MULT = 260, DIV = 261, - INTEGER = 262 + INTEGER = 262, + NEWLINE = 263 }; #endif @@ -134,13 +136,13 @@ extern int yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 15 "parser/cppython.y" +#line 17 "parser/cppython.y" int value; char* op; ast_node* expression; -#line 144 "parser/parser.c" +#line 146 "parser/parser.c" }; typedef union YYSTYPE YYSTYPE; @@ -457,21 +459,21 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 6 +#define YYFINAL 2 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 10 +#define YYLAST 14 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 8 +#define YYNTOKENS 9 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 5 +#define YYNNTS 6 /* YYNRULES -- Number of rules. */ -#define YYNRULES 10 +#define YYNRULES 13 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 15 +#define YYNSTATES 20 #define YYUNDEFTOK 2 -#define YYMAXUTOK 262 +#define YYMAXUTOK 263 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM @@ -509,25 +511,25 @@ static const yytype_int8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7 + 5, 6, 7, 8 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int8 yyrline[] = { - 0, 31, 31, 32, 35, 36, 37, 40, 41, 42, - 45 + 0, 34, 34, 35, 38, 39, 40, 43, 44, 45, + 48, 49, 50, 53 }; #endif -#if YYDEBUG || YYERROR_VERBOSE || 0 +#if YYDEBUG || YYERROR_VERBOSE || 1 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "ADD", "SUB", "MULT", "DIV", "INTEGER", - "$accept", "input", "expr", "term", "factor", YY_NULLPTR + "NEWLINE", "$accept", "input", "line", "expr", "term", "factor", YY_NULLPTR }; #endif @@ -536,11 +538,11 @@ static const char *const yytname[] = (internal) symbol number NUM (which must be that of a token). */ static const yytype_int16 yytoknum[] = { - 0, 256, 257, 258, 259, 260, 261, 262 + 0, 256, 257, 258, 259, 260, 261, 262, 263 }; # endif -#define YYPACT_NINF (-6) +#define YYPACT_NINF (-9) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) @@ -554,8 +556,8 @@ static const yytype_int16 yytoknum[] = STATE-NUM. */ static const yytype_int8 yypact[] = { - -5, -6, 5, -6, -3, -2, -6, -5, -5, -5, - -5, -6, -6, -6, -6 + -9, 0, -9, -2, -9, -9, -9, 5, -1, 4, + -9, -9, 7, 7, 7, 7, -9, -9, -9, -9 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -563,20 +565,20 @@ static const yytype_int8 yypact[] = means the default is an error. */ static const yytype_int8 yydefact[] = { - 2, 10, 0, 3, 6, 9, 1, 0, 0, 0, - 0, 4, 5, 7, 8 + 2, 0, 1, 0, 13, 4, 3, 0, 9, 12, + 6, 5, 0, 0, 0, 0, 7, 8, 10, 11 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -6, -6, -6, -1, 0 + -9, -9, -9, -9, -8, -3 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 2, 3, 4, 5 + -1, 1, 6, 7, 8, 9 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -584,36 +586,36 @@ static const yytype_int8 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int8 yytable[] = { - 7, 8, 1, 9, 10, 6, 11, 12, 0, 13, - 14 + 2, 3, 12, 13, 16, 17, 10, 4, 5, 14, + 15, 18, 19, 11, 4 }; static const yytype_int8 yycheck[] = { - 3, 4, 7, 5, 6, 0, 7, 8, -1, 9, - 10 + 0, 1, 3, 4, 12, 13, 8, 7, 8, 5, + 6, 14, 15, 8, 7 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { - 0, 7, 9, 10, 11, 12, 0, 3, 4, 5, - 6, 11, 11, 12, 12 + 0, 10, 0, 1, 7, 8, 11, 12, 13, 14, + 8, 8, 3, 4, 5, 6, 13, 13, 14, 14 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_int8 yyr1[] = { - 0, 8, 9, 9, 10, 10, 10, 11, 11, 11, - 12 + 0, 9, 10, 10, 11, 11, 11, 12, 12, 12, + 13, 13, 13, 14 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_int8 yyr2[] = { - 0, 2, 0, 1, 3, 3, 1, 3, 3, 1, - 1 + 0, 2, 0, 2, 1, 2, 2, 3, 3, 1, + 3, 3, 1, 1 }; @@ -1309,61 +1311,79 @@ yyparse (void) switch (yyn) { case 2: -#line 31 "parser/cppython.y" - { create_empy_ast(); } -#line 1315 "parser/parser.c" +#line 34 "parser/cppython.y" + { create_empy_ast(); } +#line 1317 "parser/parser.c" break; case 3: -#line 32 "parser/cppython.y" - { create_ast((yyvsp[0].expression)); } -#line 1321 "parser/parser.c" +#line 35 "parser/cppython.y" + { create_empy_ast(); } +#line 1323 "parser/parser.c" break; case 4: -#line 35 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("+", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1327 "parser/parser.c" +#line 38 "parser/cppython.y" + { create_empy_ast(); } +#line 1329 "parser/parser.c" break; case 5: -#line 36 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("-", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1333 "parser/parser.c" +#line 39 "parser/cppython.y" + { create_ast((yyvsp[-1].expression)); } +#line 1335 "parser/parser.c" break; case 6: -#line 37 "parser/cppython.y" - { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1339 "parser/parser.c" +#line 40 "parser/cppython.y" + { yyerrok; } +#line 1341 "parser/parser.c" break; case 7: -#line 40 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("*", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1345 "parser/parser.c" +#line 43 "parser/cppython.y" + { (yyval.expression) = create_bin_expr("+", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1347 "parser/parser.c" break; case 8: -#line 41 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("/", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1351 "parser/parser.c" +#line 44 "parser/cppython.y" + { (yyval.expression) = create_bin_expr("-", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1353 "parser/parser.c" break; case 9: -#line 42 "parser/cppython.y" - { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1357 "parser/parser.c" +#line 45 "parser/cppython.y" + { (yyval.expression) = print_exp((yyvsp[0].expression)); } +#line 1359 "parser/parser.c" break; case 10: -#line 45 "parser/cppython.y" - { (yyval.expression) = create_int_expr((yyvsp[0].value)); } -#line 1363 "parser/parser.c" +#line 48 "parser/cppython.y" + { (yyval.expression) = create_bin_expr("*", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1365 "parser/parser.c" break; + case 11: +#line 49 "parser/cppython.y" + { (yyval.expression) = create_bin_expr("/", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1371 "parser/parser.c" + break; -#line 1367 "parser/parser.c" + case 12: +#line 50 "parser/cppython.y" + { (yyval.expression) = print_exp((yyvsp[0].expression)); } +#line 1377 "parser/parser.c" + break; + + case 13: +#line 53 "parser/cppython.y" + { (yyval.expression) = create_int_expr((yyvsp[0].value)); } +#line 1383 "parser/parser.c" + break; + + +#line 1387 "parser/parser.c" default: break; } @@ -1595,9 +1615,10 @@ yyparse (void) #endif return yyresult; } -#line 48 "parser/cppython.y" +#line 56 "parser/cppython.y" -void yyerror(char *s) { - printf("%s\n", s); +void yyerror(const char *s) { + printf("\nSyntaxError: %s in line %d, column %d.\n", + s, parser_line, parser_column); } diff --git a/src/parser/parser.h b/src/parser/parser.h index 7486c3d..103c50b 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -53,7 +53,8 @@ extern int yydebug; SUB = 259, MULT = 260, DIV = 261, - INTEGER = 262 + INTEGER = 262, + NEWLINE = 263 }; #endif @@ -61,13 +62,13 @@ extern int yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 15 "parser/cppython.y" +#line 17 "parser/cppython.y" int value; char* op; ast_node* expression; -#line 71 "parser/parser.h" +#line 72 "parser/parser.h" }; typedef union YYSTYPE YYSTYPE; diff --git a/src/parser/parser.output b/src/parser/parser.output index 7135396..57482dc 100644 --- a/src/parser/parser.output +++ b/src/parser/parser.output @@ -3,175 +3,222 @@ Grammar 0 $accept: input $end 1 input: %empty - 2 | expr + 2 | input line - 3 expr: term ADD term - 4 | term SUB term - 5 | term + 3 line: NEWLINE + 4 | expr NEWLINE + 5 | error NEWLINE - 6 term: factor MULT factor - 7 | factor DIV factor - 8 | factor + 6 expr: term ADD term + 7 | term SUB term + 8 | term - 9 factor: INTEGER + 9 term: factor MULT factor + 10 | factor DIV factor + 11 | factor + + 12 factor: INTEGER Terminals, with rules where they appear $end (0) 0 - error (256) - ADD (258) 3 - SUB (259) 4 - MULT (260) 6 - DIV (261) 7 - INTEGER (262) 9 + error (256) 5 + ADD (258) 6 + SUB (259) 7 + MULT (260) 9 + DIV (261) 10 + INTEGER (262) 12 + NEWLINE (263) 3 4 5 Nonterminals, with rules where they appear - $accept (8) + $accept (9) on left: 0 - input (9) + input (10) on left: 1 2 - on right: 0 - expr (10) + on right: 0 2 + line (11) on left: 3 4 5 on right: 2 - term (11) + expr (12) on left: 6 7 8 - on right: 3 4 5 - factor (12) - on left: 9 + on right: 4 + term (13) + on left: 9 10 11 on right: 6 7 8 + factor (14) + on left: 12 + on right: 9 10 11 State 0 0 $accept: . input $end - INTEGER shift, and go to state 1 - $default reduce using rule 1 (input) - input go to state 2 - expr go to state 3 - term go to state 4 - factor go to state 5 + input go to state 1 State 1 - 9 factor: INTEGER . + 0 $accept: input . $end + 2 input: input . line - $default reduce using rule 9 (factor) + $end shift, and go to state 2 + error shift, and go to state 3 + INTEGER shift, and go to state 4 + NEWLINE shift, and go to state 5 + + line go to state 6 + expr go to state 7 + term go to state 8 + factor go to state 9 State 2 - 0 $accept: input . $end + 0 $accept: input $end . - $end shift, and go to state 6 + $default accept State 3 - 2 input: expr . + 5 line: error . NEWLINE - $default reduce using rule 2 (input) + NEWLINE shift, and go to state 10 State 4 - 3 expr: term . ADD term - 4 | term . SUB term - 5 | term . + 12 factor: INTEGER . - ADD shift, and go to state 7 - SUB shift, and go to state 8 - - $default reduce using rule 5 (expr) + $default reduce using rule 12 (factor) State 5 - 6 term: factor . MULT factor - 7 | factor . DIV factor - 8 | factor . - - MULT shift, and go to state 9 - DIV shift, and go to state 10 + 3 line: NEWLINE . - $default reduce using rule 8 (term) + $default reduce using rule 3 (line) State 6 - 0 $accept: input $end . + 2 input: input line . - $default accept + $default reduce using rule 2 (input) State 7 - 3 expr: term ADD . term + 4 line: expr . NEWLINE - INTEGER shift, and go to state 1 - - term go to state 11 - factor go to state 5 + NEWLINE shift, and go to state 11 State 8 - 4 expr: term SUB . term + 6 expr: term . ADD term + 7 | term . SUB term + 8 | term . - INTEGER shift, and go to state 1 + ADD shift, and go to state 12 + SUB shift, and go to state 13 - term go to state 12 - factor go to state 5 + $default reduce using rule 8 (expr) State 9 - 6 term: factor MULT . factor + 9 term: factor . MULT factor + 10 | factor . DIV factor + 11 | factor . - INTEGER shift, and go to state 1 + MULT shift, and go to state 14 + DIV shift, and go to state 15 - factor go to state 13 + $default reduce using rule 11 (term) State 10 - 7 term: factor DIV . factor - - INTEGER shift, and go to state 1 + 5 line: error NEWLINE . - factor go to state 14 + $default reduce using rule 5 (line) State 11 - 3 expr: term ADD term . + 4 line: expr NEWLINE . - $default reduce using rule 3 (expr) + $default reduce using rule 4 (line) State 12 - 4 expr: term SUB term . + 6 expr: term ADD . term - $default reduce using rule 4 (expr) + INTEGER shift, and go to state 4 + + term go to state 16 + factor go to state 9 State 13 - 6 term: factor MULT factor . + 7 expr: term SUB . term + + INTEGER shift, and go to state 4 - $default reduce using rule 6 (term) + term go to state 17 + factor go to state 9 State 14 - 7 term: factor DIV factor . + 9 term: factor MULT . factor + + INTEGER shift, and go to state 4 + + factor go to state 18 + + +State 15 + + 10 term: factor DIV . factor + + INTEGER shift, and go to state 4 + + factor go to state 19 + + +State 16 + + 6 expr: term ADD term . + + $default reduce using rule 6 (expr) + + +State 17 + + 7 expr: term SUB term . + + $default reduce using rule 7 (expr) + + +State 18 + + 9 term: factor MULT factor . + + $default reduce using rule 9 (term) + + +State 19 + + 10 term: factor DIV factor . - $default reduce using rule 7 (term) + $default reduce using rule 10 (term) diff --git a/src/tests/parser/invalid_1.ppy b/src/tests/parser/invalid_1.ppy index b297393..724a241 100644 --- a/src/tests/parser/invalid_1.ppy +++ b/src/tests/parser/invalid_1.ppy @@ -1 +1,2 @@ -1 ^ +1 + [ +@ From 734974ee3dd343eef892683f276b7437e38949f6 Mon Sep 17 00:00:00 2001 From: Dayanne Fernandes Date: Fri, 30 Oct 2020 01:03:26 -0300 Subject: [PATCH 04/10] fix ast after some error grammar rule --- src/core/ast.c | 7 ++----- src/core/ast.h | 2 +- src/core/main.c | 3 ++- src/parser/cppython.y | 2 +- src/parser/parser.c | 28 +++++++++++----------------- src/tests/parser/valid_1.ppy | 2 +- 6 files changed, 18 insertions(+), 26 deletions(-) diff --git a/src/core/ast.c b/src/core/ast.c index b0b6989..2f0fdb9 100644 --- a/src/core/ast.c +++ b/src/core/ast.c @@ -35,11 +35,8 @@ void create_empy_ast() { ast_node* print_exp(ast_node* node) { if (PARSER_VERBOSE) { - if (node == NULL) { - printf("Empty expression.\n"); - } else { - printf("TAG: %d\n", node->tag); - } + if (node == NULL) printf("Empty expression.\n"); + else printf("TAG: %d\n", node->tag); } return node; } diff --git a/src/core/ast.h b/src/core/ast.h index bba4d46..522d4bc 100644 --- a/src/core/ast.h +++ b/src/core/ast.h @@ -6,7 +6,7 @@ int lex_line, lex_column, parser_line, parser_column; enum TAG { INTEGER_TYPE=0, - VAR_TYPE, + VAR_TYPE, BINARY_TYPE }; diff --git a/src/core/main.c b/src/core/main.c index 86f0eb6..306cb46 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -6,7 +6,8 @@ int main (int argc, char* argv[]) { printf("Welcome to CPPython interpreter:\n"); - MAIN_VERBOSE = LEX_VERBOSE = PARSER_VERBOSE = AST_LVL = 0; + MAIN_VERBOSE = LEX_VERBOSE = PARSER_VERBOSE = 0; + AST_LVL = 0; root = NULL; // init lexer and parser diff --git a/src/parser/cppython.y b/src/parser/cppython.y index 04b31e8..d02492b 100644 --- a/src/parser/cppython.y +++ b/src/parser/cppython.y @@ -32,7 +32,7 @@ %% input : /* empty */ { create_empy_ast(); } - | input line { create_empy_ast(); } + | input line line : NEWLINE { create_empy_ast(); } diff --git a/src/parser/parser.c b/src/parser/parser.c index 27742e6..1067195 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -1316,74 +1316,68 @@ yyparse (void) #line 1317 "parser/parser.c" break; - case 3: -#line 35 "parser/cppython.y" - { create_empy_ast(); } -#line 1323 "parser/parser.c" - break; - case 4: #line 38 "parser/cppython.y" { create_empy_ast(); } -#line 1329 "parser/parser.c" +#line 1323 "parser/parser.c" break; case 5: #line 39 "parser/cppython.y" { create_ast((yyvsp[-1].expression)); } -#line 1335 "parser/parser.c" +#line 1329 "parser/parser.c" break; case 6: #line 40 "parser/cppython.y" { yyerrok; } -#line 1341 "parser/parser.c" +#line 1335 "parser/parser.c" break; case 7: #line 43 "parser/cppython.y" { (yyval.expression) = create_bin_expr("+", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1347 "parser/parser.c" +#line 1341 "parser/parser.c" break; case 8: #line 44 "parser/cppython.y" { (yyval.expression) = create_bin_expr("-", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1353 "parser/parser.c" +#line 1347 "parser/parser.c" break; case 9: #line 45 "parser/cppython.y" { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1359 "parser/parser.c" +#line 1353 "parser/parser.c" break; case 10: #line 48 "parser/cppython.y" { (yyval.expression) = create_bin_expr("*", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1365 "parser/parser.c" +#line 1359 "parser/parser.c" break; case 11: #line 49 "parser/cppython.y" { (yyval.expression) = create_bin_expr("/", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1371 "parser/parser.c" +#line 1365 "parser/parser.c" break; case 12: #line 50 "parser/cppython.y" { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1377 "parser/parser.c" +#line 1371 "parser/parser.c" break; case 13: #line 53 "parser/cppython.y" { (yyval.expression) = create_int_expr((yyvsp[0].value)); } -#line 1383 "parser/parser.c" +#line 1377 "parser/parser.c" break; -#line 1387 "parser/parser.c" +#line 1381 "parser/parser.c" default: break; } diff --git a/src/tests/parser/valid_1.ppy b/src/tests/parser/valid_1.ppy index 645e6d9..a922b77 100644 --- a/src/tests/parser/valid_1.ppy +++ b/src/tests/parser/valid_1.ppy @@ -1 +1 @@ -1 / 1 +2 + 2 From 5d8fe3871e2e59f9f6b612a8c5b7a6834815341f Mon Sep 17 00:00:00 2001 From: Dayanne Fernandes Date: Fri, 30 Oct 2020 01:16:28 -0300 Subject: [PATCH 05/10] add stmt, arith grammar rules --- src/parser/cppython.y | 32 +++--- src/parser/parser.c | 122 +++++++++++++---------- src/parser/parser.output | 203 ++++++++++++++++++++++----------------- 3 files changed, 201 insertions(+), 156 deletions(-) diff --git a/src/parser/cppython.y b/src/parser/cppython.y index d02492b..4f4fdd5 100644 --- a/src/parser/cppython.y +++ b/src/parser/cppython.y @@ -27,30 +27,34 @@ %left ADD SUB %left MULT DIV -%type expr term factor +%type stmt simple_stmt arith_expr term factor %% -input : /* empty */ { create_empy_ast(); } - | input line +input : /* empty */ { create_empy_ast(); } + | line -line : NEWLINE { create_empy_ast(); } - | expr NEWLINE { create_ast($1); } - | error NEWLINE { yyerrok; } +line : NEWLINE { create_empy_ast(); } + | stmt[U] NEWLINE { create_ast($U); } + | error NEWLINE { yyerrok; } ; -expr : term[L] ADD term[R] { $$ = create_bin_expr("+", $L, $R); } - | term[L] SUB term[R] { $$ = create_bin_expr("-", $L, $R); } - | term[U] { $$ = print_exp($U); } - ; +stmt : simple_stmt[U] { $$ = print_exp($U); } -term : factor[L] MULT factor[R] { $$ = create_bin_expr("*", $L, $R); } - | factor[L] DIV factor[R] { $$ = create_bin_expr("/", $L, $R); } - | factor[U] { $$ = print_exp($U); } +simple_stmt : arith_expr[U] { $$ = print_exp($U); } + +arith_expr : term[L] ADD term[R] { $$ = create_bin_expr("+", $L, $R); } + | term[L] SUB term[R] { $$ = create_bin_expr("-", $L, $R); } + | term[U] { $$ = print_exp($U); } + ; + +term : factor[L] MULT factor[R] { $$ = create_bin_expr("*", $L, $R); } + | factor[L] DIV factor[R] { $$ = create_bin_expr("/", $L, $R); } + | factor[U] { $$ = print_exp($U); } ; -factor : INTEGER[U] { $$ = create_int_expr($U); } +factor : INTEGER[U] { $$ = create_int_expr($U); } ; %% diff --git a/src/parser/parser.c b/src/parser/parser.c index 1067195..b977619 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -459,18 +459,18 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 2 +#define YYFINAL 12 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 14 +#define YYLAST 15 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 9 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 6 +#define YYNNTS 8 /* YYNRULES -- Number of rules. */ -#define YYNRULES 13 +#define YYNRULES 15 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 20 +#define YYNSTATES 22 #define YYUNDEFTOK 2 #define YYMAXUTOK 263 @@ -518,8 +518,8 @@ static const yytype_int8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int8 yyrline[] = { - 0, 34, 34, 35, 38, 39, 40, 43, 44, 45, - 48, 49, 50, 53 + 0, 34, 34, 35, 38, 39, 40, 43, 45, 47, + 48, 49, 52, 53, 54, 57 }; #endif @@ -529,7 +529,8 @@ static const yytype_int8 yyrline[] = static const char *const yytname[] = { "$end", "error", "$undefined", "ADD", "SUB", "MULT", "DIV", "INTEGER", - "NEWLINE", "$accept", "input", "line", "expr", "term", "factor", YY_NULLPTR + "NEWLINE", "$accept", "input", "line", "stmt", "simple_stmt", + "arith_expr", "term", "factor", YY_NULLPTR }; #endif @@ -542,12 +543,12 @@ static const yytype_int16 yytoknum[] = }; # endif -#define YYPACT_NINF (-9) +#define YYPACT_NINF (-11) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) -#define YYTABLE_NINF (-1) +#define YYTABLE_NINF (-3) #define yytable_value_is_error(Yyn) \ 0 @@ -556,8 +557,9 @@ static const yytype_int16 yytoknum[] = STATE-NUM. */ static const yytype_int8 yypact[] = { - -9, 0, -9, -2, -9, -9, -9, 5, -1, 4, - -9, -9, 7, 7, 7, 7, -9, -9, -9, -9 + 0, -2, -11, -11, 13, -11, 6, -11, -11, -1, + 4, -11, -11, -11, 8, 8, 8, 8, -11, -11, + -11, -11 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -565,20 +567,21 @@ static const yytype_int8 yypact[] = means the default is an error. */ static const yytype_int8 yydefact[] = { - 2, 0, 1, 0, 13, 4, 3, 0, 9, 12, - 6, 5, 0, 0, 0, 0, 7, 8, 10, 11 + 0, 0, 15, 4, 0, 3, 0, 7, 8, 11, + 14, 6, 1, 5, 0, 0, 0, 0, 9, 10, + 12, 13 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -9, -9, -9, -9, -8, -3 + -11, -11, -11, -11, -11, -11, -10, -5 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 1, 6, 7, 8, 9 + -1, 4, 5, 6, 7, 8, 9, 10 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -586,36 +589,37 @@ static const yytype_int8 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int8 yytable[] = { - 2, 3, 12, 13, 16, 17, 10, 4, 5, 14, - 15, 18, 19, 11, 4 + -2, 1, 14, 15, 18, 19, 11, 2, 3, 16, + 17, 20, 21, 12, 13, 2 }; static const yytype_int8 yycheck[] = { - 0, 1, 3, 4, 12, 13, 8, 7, 8, 5, - 6, 14, 15, 8, 7 + 0, 1, 3, 4, 14, 15, 8, 7, 8, 5, + 6, 16, 17, 0, 8, 7 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { - 0, 10, 0, 1, 7, 8, 11, 12, 13, 14, - 8, 8, 3, 4, 5, 6, 13, 13, 14, 14 + 0, 1, 7, 8, 10, 11, 12, 13, 14, 15, + 16, 8, 0, 8, 3, 4, 5, 6, 15, 15, + 16, 16 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_int8 yyr1[] = { - 0, 9, 10, 10, 11, 11, 11, 12, 12, 12, - 13, 13, 13, 14 + 0, 9, 10, 10, 11, 11, 11, 12, 13, 14, + 14, 14, 15, 15, 15, 16 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_int8 yyr2[] = { - 0, 2, 0, 2, 1, 2, 2, 3, 3, 1, - 3, 3, 1, 1 + 0, 2, 0, 1, 1, 2, 2, 1, 1, 3, + 3, 1, 3, 3, 1, 1 }; @@ -1312,72 +1316,84 @@ yyparse (void) { case 2: #line 34 "parser/cppython.y" - { create_empy_ast(); } -#line 1317 "parser/parser.c" + { create_empy_ast(); } +#line 1321 "parser/parser.c" break; case 4: #line 38 "parser/cppython.y" - { create_empy_ast(); } -#line 1323 "parser/parser.c" + { create_empy_ast(); } +#line 1327 "parser/parser.c" break; case 5: #line 39 "parser/cppython.y" - { create_ast((yyvsp[-1].expression)); } -#line 1329 "parser/parser.c" + { create_ast((yyvsp[-1].expression)); } +#line 1333 "parser/parser.c" break; case 6: #line 40 "parser/cppython.y" - { yyerrok; } -#line 1335 "parser/parser.c" + { yyerrok; } +#line 1339 "parser/parser.c" break; case 7: #line 43 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("+", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1341 "parser/parser.c" + { (yyval.expression) = print_exp((yyvsp[0].expression)); } +#line 1345 "parser/parser.c" break; case 8: -#line 44 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("-", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1347 "parser/parser.c" +#line 45 "parser/cppython.y" + { (yyval.expression) = print_exp((yyvsp[0].expression)); } +#line 1351 "parser/parser.c" break; case 9: -#line 45 "parser/cppython.y" - { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1353 "parser/parser.c" +#line 47 "parser/cppython.y" + { (yyval.expression) = create_bin_expr("+", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1357 "parser/parser.c" break; case 10: #line 48 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("*", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1359 "parser/parser.c" + { (yyval.expression) = create_bin_expr("-", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1363 "parser/parser.c" break; case 11: #line 49 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("/", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1365 "parser/parser.c" + { (yyval.expression) = print_exp((yyvsp[0].expression)); } +#line 1369 "parser/parser.c" break; case 12: -#line 50 "parser/cppython.y" - { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1371 "parser/parser.c" +#line 52 "parser/cppython.y" + { (yyval.expression) = create_bin_expr("*", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1375 "parser/parser.c" break; case 13: #line 53 "parser/cppython.y" - { (yyval.expression) = create_int_expr((yyvsp[0].value)); } -#line 1377 "parser/parser.c" + { (yyval.expression) = create_bin_expr("/", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1381 "parser/parser.c" + break; + + case 14: +#line 54 "parser/cppython.y" + { (yyval.expression) = print_exp((yyvsp[0].expression)); } +#line 1387 "parser/parser.c" + break; + + case 15: +#line 57 "parser/cppython.y" + { (yyval.expression) = create_int_expr((yyvsp[0].value)); } +#line 1393 "parser/parser.c" break; -#line 1381 "parser/parser.c" +#line 1397 "parser/parser.c" default: break; } @@ -1609,7 +1625,7 @@ yyparse (void) #endif return yyresult; } -#line 56 "parser/cppython.y" +#line 60 "parser/cppython.y" void yyerror(const char *s) { diff --git a/src/parser/parser.output b/src/parser/parser.output index 57482dc..ddbc938 100644 --- a/src/parser/parser.output +++ b/src/parser/parser.output @@ -3,32 +3,36 @@ Grammar 0 $accept: input $end 1 input: %empty - 2 | input line + 2 | line 3 line: NEWLINE - 4 | expr NEWLINE + 4 | stmt NEWLINE 5 | error NEWLINE - 6 expr: term ADD term - 7 | term SUB term - 8 | term + 6 stmt: simple_stmt - 9 term: factor MULT factor - 10 | factor DIV factor - 11 | factor + 7 simple_stmt: arith_expr - 12 factor: INTEGER + 8 arith_expr: term ADD term + 9 | term SUB term + 10 | term + + 11 term: factor MULT factor + 12 | factor DIV factor + 13 | factor + + 14 factor: INTEGER Terminals, with rules where they appear $end (0) 0 error (256) 5 - ADD (258) 6 - SUB (259) 7 - MULT (260) 9 - DIV (261) 10 - INTEGER (262) 12 + ADD (258) 8 + SUB (259) 9 + MULT (260) 11 + DIV (261) 12 + INTEGER (262) 14 NEWLINE (263) 3 4 5 @@ -38,187 +42,208 @@ Nonterminals, with rules where they appear on left: 0 input (10) on left: 1 2 - on right: 0 2 + on right: 0 line (11) on left: 3 4 5 on right: 2 - expr (12) - on left: 6 7 8 + stmt (12) + on left: 6 on right: 4 - term (13) - on left: 9 10 11 - on right: 6 7 8 - factor (14) - on left: 12 - on right: 9 10 11 + simple_stmt (13) + on left: 7 + on right: 6 + arith_expr (14) + on left: 8 9 10 + on right: 7 + term (15) + on left: 11 12 13 + on right: 8 9 10 + factor (16) + on left: 14 + on right: 11 12 13 State 0 0 $accept: . input $end - $default reduce using rule 1 (input) + error shift, and go to state 1 + INTEGER shift, and go to state 2 + NEWLINE shift, and go to state 3 - input go to state 1 + $end reduce using rule 1 (input) + input go to state 4 + line go to state 5 + stmt go to state 6 + simple_stmt go to state 7 + arith_expr go to state 8 + term go to state 9 + factor go to state 10 -State 1 - 0 $accept: input . $end - 2 input: input . line +State 1 - $end shift, and go to state 2 - error shift, and go to state 3 - INTEGER shift, and go to state 4 - NEWLINE shift, and go to state 5 + 5 line: error . NEWLINE - line go to state 6 - expr go to state 7 - term go to state 8 - factor go to state 9 + NEWLINE shift, and go to state 11 State 2 - 0 $accept: input $end . + 14 factor: INTEGER . - $default accept + $default reduce using rule 14 (factor) State 3 - 5 line: error . NEWLINE + 3 line: NEWLINE . - NEWLINE shift, and go to state 10 + $default reduce using rule 3 (line) State 4 - 12 factor: INTEGER . + 0 $accept: input . $end - $default reduce using rule 12 (factor) + $end shift, and go to state 12 State 5 - 3 line: NEWLINE . + 2 input: line . - $default reduce using rule 3 (line) + $default reduce using rule 2 (input) State 6 - 2 input: input line . + 4 line: stmt . NEWLINE - $default reduce using rule 2 (input) + NEWLINE shift, and go to state 13 State 7 - 4 line: expr . NEWLINE + 6 stmt: simple_stmt . - NEWLINE shift, and go to state 11 + $default reduce using rule 6 (stmt) State 8 - 6 expr: term . ADD term - 7 | term . SUB term - 8 | term . - - ADD shift, and go to state 12 - SUB shift, and go to state 13 + 7 simple_stmt: arith_expr . - $default reduce using rule 8 (expr) + $default reduce using rule 7 (simple_stmt) State 9 - 9 term: factor . MULT factor - 10 | factor . DIV factor - 11 | factor . + 8 arith_expr: term . ADD term + 9 | term . SUB term + 10 | term . - MULT shift, and go to state 14 - DIV shift, and go to state 15 + ADD shift, and go to state 14 + SUB shift, and go to state 15 - $default reduce using rule 11 (term) + $default reduce using rule 10 (arith_expr) State 10 - 5 line: error NEWLINE . + 11 term: factor . MULT factor + 12 | factor . DIV factor + 13 | factor . - $default reduce using rule 5 (line) + MULT shift, and go to state 16 + DIV shift, and go to state 17 + + $default reduce using rule 13 (term) State 11 - 4 line: expr NEWLINE . + 5 line: error NEWLINE . - $default reduce using rule 4 (line) + $default reduce using rule 5 (line) State 12 - 6 expr: term ADD . term - - INTEGER shift, and go to state 4 + 0 $accept: input $end . - term go to state 16 - factor go to state 9 + $default accept State 13 - 7 expr: term SUB . term - - INTEGER shift, and go to state 4 + 4 line: stmt NEWLINE . - term go to state 17 - factor go to state 9 + $default reduce using rule 4 (line) State 14 - 9 term: factor MULT . factor + 8 arith_expr: term ADD . term - INTEGER shift, and go to state 4 + INTEGER shift, and go to state 2 - factor go to state 18 + term go to state 18 + factor go to state 10 State 15 - 10 term: factor DIV . factor + 9 arith_expr: term SUB . term - INTEGER shift, and go to state 4 + INTEGER shift, and go to state 2 - factor go to state 19 + term go to state 19 + factor go to state 10 State 16 - 6 expr: term ADD term . + 11 term: factor MULT . factor + + INTEGER shift, and go to state 2 - $default reduce using rule 6 (expr) + factor go to state 20 State 17 - 7 expr: term SUB term . + 12 term: factor DIV . factor - $default reduce using rule 7 (expr) + INTEGER shift, and go to state 2 + + factor go to state 21 State 18 - 9 term: factor MULT factor . + 8 arith_expr: term ADD term . - $default reduce using rule 9 (term) + $default reduce using rule 8 (arith_expr) State 19 - 10 term: factor DIV factor . + 9 arith_expr: term SUB term . + + $default reduce using rule 9 (arith_expr) + + +State 20 + + 11 term: factor MULT factor . + + $default reduce using rule 11 (term) + + +State 21 + + 12 term: factor DIV factor . - $default reduce using rule 10 (term) + $default reduce using rule 12 (term) From 97fb7c369fc0211e3eb6f6aa4c365467eb375878 Mon Sep 17 00:00:00 2001 From: Dayanne Fernandes Date: Fri, 30 Oct 2020 01:48:07 -0300 Subject: [PATCH 06/10] fix gorgeous ast print func --- src/core/ast.c | 20 ++-- src/core/ast.h | 7 +- src/core/main.c | 3 +- src/lexer/cppython.lex | 19 +++- src/lexer/lexer.c | 108 +++++++++++--------- src/lexer/lexer.h | 2 +- src/parser/cppython.y | 39 +++---- src/parser/parser.c | 168 ++++++++++++++++--------------- src/parser/parser.h | 11 +- src/parser/parser.output | 190 ++++++++++++++++++++--------------- src/tests/parser/valid_1.ppy | 2 +- 11 files changed, 327 insertions(+), 242 deletions(-) diff --git a/src/core/ast.c b/src/core/ast.c index 2f0fdb9..68a8882 100644 --- a/src/core/ast.c +++ b/src/core/ast.c @@ -1,5 +1,6 @@ -#include +#include #include +#include #include "ast.h" ast_node* create_bin_expr(char* operator, ast_node* left, ast_node* right) { @@ -21,6 +22,14 @@ ast_node* create_int_expr(int value) { return expr; } +ast_node* create_var_expr(char* value) { + if (PARSER_VERBOSE) printf("\n\nCreating variable expression node: %s\n", value); + ast_node* expr = (ast_node*) malloc(sizeof(ast_node)); + expr->tag = VAR_TYPE; + strcpy(expr->op.variable_expr, value); + return expr; +} + void create_ast(ast_node* expression) { if (PARSER_VERBOSE) printf("\nCreating AST.\n"); root = expression; @@ -41,7 +50,7 @@ ast_node* print_exp(ast_node* node) { return node; } -void print_ast(ast_node* node) { +void print_ast(ast_node* node, int lvl) { if (node == NULL) { printf("Empty AST.\n"); return; @@ -49,7 +58,7 @@ void print_ast(ast_node* node) { if (PARSER_VERBOSE) printf("TAG: %d\n", node->tag); - for (int i=0; i < AST_LVL; ++i) printf(" "); + for (int i=0; i < lvl; ++i) printf(" "); // terminal leaf if (node->tag == INTEGER_TYPE) { @@ -62,9 +71,8 @@ void print_ast(ast_node* node) { // non terminal node } else if (node->tag == BINARY_TYPE) { printf("OP: %s\n", node->op.binary_expr.operator); - AST_LVL += 1; - print_ast(node->op.binary_expr.right); - print_ast(node->op.binary_expr.left); + print_ast(node->op.binary_expr.right, lvl+1); + print_ast(node->op.binary_expr.left, lvl+1); } else { printf("Print AST unknown error.\n"); return; diff --git a/src/core/ast.h b/src/core/ast.h index 522d4bc..b66f05d 100644 --- a/src/core/ast.h +++ b/src/core/ast.h @@ -1,7 +1,7 @@ #ifndef __AST_H__ #define __AST_H__ -int LEX_VERBOSE, PARSER_VERBOSE, MAIN_VERBOSE, AST_LVL; +int LEX_VERBOSE, PARSER_VERBOSE, MAIN_VERBOSE; int lex_line, lex_column, parser_line, parser_column; enum TAG { @@ -14,7 +14,7 @@ typedef struct exp { int tag; union { int integer_expr; - char* variable_expr; + char variable_expr[79]; struct { char* operator; struct exp* left; @@ -25,12 +25,13 @@ typedef struct exp { ast_node* root; -void print_ast(ast_node* node); +void print_ast(ast_node* node, int lvl); ast_node* print_exp(ast_node* node); void create_empy_ast(); void create_ast(ast_node* expression); ast_node* create_int_expr(int value); +ast_node* create_var_expr(char* value); ast_node* create_bin_expr(char* operator, ast_node* left, ast_node* right); void handle_token(int token); diff --git a/src/core/main.c b/src/core/main.c index 306cb46..d789972 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -7,7 +7,6 @@ int main (int argc, char* argv[]) { printf("Welcome to CPPython interpreter:\n"); MAIN_VERBOSE = LEX_VERBOSE = PARSER_VERBOSE = 0; - AST_LVL = 0; root = NULL; // init lexer and parser @@ -22,7 +21,7 @@ int main (int argc, char* argv[]) { printf("\nLexer and parser finished.\n\n"); printf("Abstract Syntax Tree:\n"); - print_ast(root); + print_ast(root, 0); printf("\nSymbol Table:\n"); print_st(); diff --git a/src/lexer/cppython.lex b/src/lexer/cppython.lex index 03cb351..96e8551 100644 --- a/src/lexer/cppython.lex +++ b/src/lexer/cppython.lex @@ -1,6 +1,7 @@ /* tokens mapping */ %{ + #include #include #include "sym_tab.h" #include "ast.h" @@ -11,7 +12,9 @@ NEWLINE_TOK, WHITESPACE_TOK, ID_TOK, + ASSIGN_TOK, KEYWORD_TOK, + VAR_TOK, FLOAT_TOK, DELIMITER_TOK, BOOLEAN_TOK, @@ -42,7 +45,8 @@ MULT ("*") DIV ("/") OPERATOR (ADD|SUB|MULT|DIV) BOOLEAN_OP ("=="|"<="|">="|"!="|"<"|">"|"~"|"|"|"&"|"and"|"or"|"not") -DELIMITER ("="|"("|")"|"["|"]"|";"|","|"."|":") +ASSIGN ("=") +DELIMITER ("("|")"|"["|"]"|";"|","|"."|":") BOOLEAN ("True"|"False") NULL ("None") NEWLINE (\n) @@ -67,6 +71,7 @@ NUMBER ({INTEGER}|{FLOAT}) {ADD} { handle_token(ADD_TOK); return ADD; }; {MULT} { handle_token(MULT_TOK); return MULT; }; {DIV} { handle_token(DIV_TOK); return DIV; }; +{ASSIGN} { handle_token(ASSIGN_TOK); return ASSIGN; }; {DELIMITER} ; /* conditional and booleans expressions */ @@ -83,7 +88,7 @@ NUMBER ({INTEGER}|{FLOAT}) {NEWLINE} { handle_token(NEWLINE_TOK); return NEWLINE; }; {WHITESPACE} ; -{VAR} ; +{VAR} { handle_token(ID_TOK); return ID; }; . { handle_token(ERROR_TOK); }; /* any character but newline */ %% @@ -99,7 +104,7 @@ void handle_token(int token) { switch (token) { case INTEGER_TOK: if (LEX_VERBOSE) printf("Token: ", yytext); - yylval.value = atoi(yytext); + yylval.int_value = atoi(yytext); break; case SUB_TOK: if (LEX_VERBOSE) printf("Token: ", yytext); @@ -117,6 +122,14 @@ void handle_token(int token) { if (LEX_VERBOSE) printf("Token: ", yytext); yylval.op = yytext; break; + case ID_TOK: + if (LEX_VERBOSE) printf("Token: ", yytext); + strcpy(yylval.var, yytext); + break; + case ASSIGN_TOK: + if (LEX_VERBOSE) printf("Token: ", yytext); + yylval.op = yytext; + break; case NEWLINE_TOK: parser_line = lex_line; parser_column = lex_column; diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index 3a2fae9..af8d7d7 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -371,8 +371,8 @@ static void yynoreturn yy_fatal_error ( const char* msg ); (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 17 -#define YY_END_OF_BUFFER 18 +#define YY_NUM_RULES 18 +#define YY_END_OF_BUFFER 19 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -382,14 +382,14 @@ struct yy_trans_info }; static const flex_int16_t yy_accept[80] = { 0, - 0, 0, 18, 16, 14, 13, 16, 16, 16, 10, - 16, 8, 6, 5, 4, 7, 2, 2, 10, 8, - 10, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 16, 14, 10, 0, 12, - 0, 11, 0, 12, 0, 3, 0, 2, 15, 15, - 15, 15, 15, 15, 15, 1, 15, 15, 10, 15, - 15, 15, 3, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 9, 15, 15, 15, 15, 15, 0 + 0, 0, 19, 17, 15, 14, 17, 17, 17, 11, + 17, 9, 6, 5, 4, 7, 2, 2, 11, 8, + 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 17, 15, 11, 0, 13, + 0, 12, 0, 13, 0, 3, 0, 2, 16, 16, + 16, 16, 16, 16, 16, 1, 16, 16, 11, 16, + 16, 16, 3, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 10, 16, 16, 16, 16, 16, 0 } ; static const YY_CHAR yy_ec[256] = @@ -506,9 +506,9 @@ static const flex_int16_t yy_chk[180] = } ; /* Table of booleans, true if rule could match eol. */ -static const flex_int32_t yy_rule_can_match_eol[18] = +static const flex_int32_t yy_rule_can_match_eol[19] = { 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, }; +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, }; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; @@ -527,6 +527,7 @@ char *yytext; #line 1 "lexer/cppython.lex" /* tokens mapping */ #line 4 "lexer/cppython.lex" + #include #include #include "sym_tab.h" #include "ast.h" @@ -537,7 +538,9 @@ char *yytext; NEWLINE_TOK, WHITESPACE_TOK, ID_TOK, + ASSIGN_TOK, KEYWORD_TOK, + VAR_TOK, FLOAT_TOK, DELIMITER_TOK, BOOLEAN_TOK, @@ -550,11 +553,11 @@ char *yytext; MULT_TOK, DIV_TOK }; -#line 554 "lexer/lexer.c" +#line 557 "lexer/lexer.c" #define YY_NO_INPUT 1 -#line 35 "lexer/cppython.lex" +#line 38 "lexer/cppython.lex" /* regex and token definition */ -#line 558 "lexer/lexer.c" +#line 561 "lexer/lexer.c" #define INITIAL 0 @@ -769,12 +772,12 @@ YY_DECL } { -#line 57 "lexer/cppython.lex" +#line 61 "lexer/cppython.lex" /* reserved keywords */ -#line 778 "lexer/lexer.c" +#line 781 "lexer/lexer.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -843,96 +846,101 @@ YY_DECL case 1: YY_RULE_SETUP -#line 61 "lexer/cppython.lex" +#line 65 "lexer/cppython.lex" ; YY_BREAK /* arithmetic expressions */ case 2: YY_RULE_SETUP -#line 65 "lexer/cppython.lex" +#line 69 "lexer/cppython.lex" { handle_token(INTEGER_TOK); return INTEGER; }; YY_BREAK case 3: YY_RULE_SETUP -#line 66 "lexer/cppython.lex" +#line 70 "lexer/cppython.lex" ; YY_BREAK case 4: YY_RULE_SETUP -#line 67 "lexer/cppython.lex" +#line 71 "lexer/cppython.lex" { handle_token(SUB_TOK); return SUB; }; YY_BREAK case 5: YY_RULE_SETUP -#line 68 "lexer/cppython.lex" +#line 72 "lexer/cppython.lex" { handle_token(ADD_TOK); return ADD; }; YY_BREAK case 6: YY_RULE_SETUP -#line 69 "lexer/cppython.lex" +#line 73 "lexer/cppython.lex" { handle_token(MULT_TOK); return MULT; }; YY_BREAK case 7: YY_RULE_SETUP -#line 70 "lexer/cppython.lex" +#line 74 "lexer/cppython.lex" { handle_token(DIV_TOK); return DIV; }; YY_BREAK case 8: YY_RULE_SETUP -#line 71 "lexer/cppython.lex" -; +#line 75 "lexer/cppython.lex" +{ handle_token(ASSIGN_TOK); return ASSIGN; }; YY_BREAK -/* conditional and booleans expressions */ case 9: YY_RULE_SETUP -#line 75 "lexer/cppython.lex" +#line 76 "lexer/cppython.lex" ; YY_BREAK +/* conditional and booleans expressions */ case 10: YY_RULE_SETUP -#line 76 "lexer/cppython.lex" +#line 80 "lexer/cppython.lex" ; YY_BREAK -/* structure helpers */ case 11: -/* rule 11 can match eol */ YY_RULE_SETUP -#line 80 "lexer/cppython.lex" +#line 81 "lexer/cppython.lex" ; YY_BREAK +/* structure helpers */ case 12: +/* rule 12 can match eol */ YY_RULE_SETUP -#line 81 "lexer/cppython.lex" +#line 85 "lexer/cppython.lex" ; YY_BREAK -/* general */ case 13: -/* rule 13 can match eol */ YY_RULE_SETUP -#line 85 "lexer/cppython.lex" -{ handle_token(NEWLINE_TOK); return NEWLINE; }; +#line 86 "lexer/cppython.lex" +; YY_BREAK +/* general */ case 14: +/* rule 14 can match eol */ YY_RULE_SETUP -#line 86 "lexer/cppython.lex" -; +#line 90 "lexer/cppython.lex" +{ handle_token(NEWLINE_TOK); return NEWLINE; }; YY_BREAK case 15: YY_RULE_SETUP -#line 87 "lexer/cppython.lex" +#line 91 "lexer/cppython.lex" ; YY_BREAK case 16: YY_RULE_SETUP -#line 88 "lexer/cppython.lex" -{ handle_token(ERROR_TOK); }; /* any character but newline */ +#line 92 "lexer/cppython.lex" +{ handle_token(ID_TOK); return ID; }; YY_BREAK case 17: YY_RULE_SETUP -#line 90 "lexer/cppython.lex" +#line 93 "lexer/cppython.lex" +{ handle_token(ERROR_TOK); }; /* any character but newline */ + YY_BREAK +case 18: +YY_RULE_SETUP +#line 95 "lexer/cppython.lex" ECHO; YY_BREAK -#line 936 "lexer/lexer.c" +#line 944 "lexer/lexer.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -1908,7 +1916,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 90 "lexer/cppython.lex" +#line 95 "lexer/cppython.lex" /* @@ -1922,7 +1930,7 @@ void handle_token(int token) { switch (token) { case INTEGER_TOK: if (LEX_VERBOSE) printf("Token: ", yytext); - yylval.value = atoi(yytext); + yylval.int_value = atoi(yytext); break; case SUB_TOK: if (LEX_VERBOSE) printf("Token: ", yytext); @@ -1940,6 +1948,14 @@ void handle_token(int token) { if (LEX_VERBOSE) printf("Token: ", yytext); yylval.op = yytext; break; + case ID_TOK: + if (LEX_VERBOSE) printf("Token: ", yytext); + strcpy(yylval.var, yytext); + break; + case ASSIGN_TOK: + if (LEX_VERBOSE) printf("Token: ", yytext); + yylval.op = yytext; + break; case NEWLINE_TOK: parser_line = lex_line; parser_column = lex_column; diff --git a/src/lexer/lexer.h b/src/lexer/lexer.h index b6ee6dd..6a2268b 100644 --- a/src/lexer/lexer.h +++ b/src/lexer/lexer.h @@ -466,7 +466,7 @@ extern int yylex (void); #undef yyTABLES_NAME #endif -#line 90 "lexer/cppython.lex" +#line 95 "lexer/cppython.lex" #line 473 "lexer/lexer.h" diff --git a/src/parser/cppython.y b/src/parser/cppython.y index 4f4fdd5..10de57f 100644 --- a/src/parser/cppython.y +++ b/src/parser/cppython.y @@ -15,46 +15,51 @@ %start input %union { - int value; + int int_value; + char var[79]; char* op; ast_node* expression; } -%token ADD SUB MULT DIV -%token INTEGER +%token ADD SUB MULT DIV ASSIGN +%token INTEGER +%token ID %token NEWLINE +%left ASSIGN %left ADD SUB %left MULT DIV -%type stmt simple_stmt arith_expr term factor +%type stmt simple_stmt var arith_expr term factor %% -input : /* empty */ { create_empy_ast(); } +input : /* empty */ { create_empy_ast(); } | line -line : NEWLINE { create_empy_ast(); } - | stmt[U] NEWLINE { create_ast($U); } - | error NEWLINE { yyerrok; } +line : NEWLINE { create_empy_ast(); } + | stmt[U] NEWLINE { create_ast($U); } + | error NEWLINE { yyerrok; } ; -stmt : simple_stmt[U] { $$ = print_exp($U); } +stmt : simple_stmt[U] { $$ = print_exp($U); } -simple_stmt : arith_expr[U] { $$ = print_exp($U); } +simple_stmt : var[L] ASSIGN arith_expr[R] { $$ = create_bin_expr("=", $L, $R); } -arith_expr : term[L] ADD term[R] { $$ = create_bin_expr("+", $L, $R); } - | term[L] SUB term[R] { $$ = create_bin_expr("-", $L, $R); } - | term[U] { $$ = print_exp($U); } +var : ID[U] { $$ = create_var_expr($U); } + +arith_expr : term[L] ADD term[R] { $$ = create_bin_expr("+", $L, $R); } + | term[L] SUB term[R] { $$ = create_bin_expr("-", $L, $R); } + | term[U] { $$ = print_exp($U); } ; -term : factor[L] MULT factor[R] { $$ = create_bin_expr("*", $L, $R); } - | factor[L] DIV factor[R] { $$ = create_bin_expr("/", $L, $R); } - | factor[U] { $$ = print_exp($U); } +term : factor[L] MULT factor[R] { $$ = create_bin_expr("*", $L, $R); } + | factor[L] DIV factor[R] { $$ = create_bin_expr("/", $L, $R); } + | factor[U] { $$ = print_exp($U); } ; -factor : INTEGER[U] { $$ = create_int_expr($U); } +factor : INTEGER[U] { $$ = create_int_expr($U); } ; %% diff --git a/src/parser/parser.c b/src/parser/parser.c index b977619..3ef6bf7 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -127,8 +127,10 @@ extern int yydebug; SUB = 259, MULT = 260, DIV = 261, - INTEGER = 262, - NEWLINE = 263 + ASSIGN = 262, + INTEGER = 263, + ID = 264, + NEWLINE = 265 }; #endif @@ -138,11 +140,12 @@ union YYSTYPE { #line 17 "parser/cppython.y" - int value; + int int_value; + char var[79]; char* op; ast_node* expression; -#line 146 "parser/parser.c" +#line 149 "parser/parser.c" }; typedef union YYSTYPE YYSTYPE; @@ -459,21 +462,21 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 12 +#define YYFINAL 10 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 15 +#define YYLAST 17 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 9 +#define YYNTOKENS 11 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 8 +#define YYNNTS 9 /* YYNRULES -- Number of rules. */ -#define YYNRULES 15 +#define YYNRULES 16 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 22 +#define YYNSTATES 25 #define YYUNDEFTOK 2 -#define YYMAXUTOK 263 +#define YYMAXUTOK 265 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM @@ -511,15 +514,15 @@ static const yytype_int8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8 + 5, 6, 7, 8, 9, 10 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int8 yyrline[] = { - 0, 34, 34, 35, 38, 39, 40, 43, 45, 47, - 48, 49, 52, 53, 54, 57 + 0, 37, 37, 38, 41, 42, 43, 46, 48, 50, + 52, 53, 54, 57, 58, 59, 62 }; #endif @@ -528,9 +531,9 @@ static const yytype_int8 yyrline[] = First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "ADD", "SUB", "MULT", "DIV", "INTEGER", - "NEWLINE", "$accept", "input", "line", "stmt", "simple_stmt", - "arith_expr", "term", "factor", YY_NULLPTR + "$end", "error", "$undefined", "ADD", "SUB", "MULT", "DIV", "ASSIGN", + "INTEGER", "ID", "NEWLINE", "$accept", "input", "line", "stmt", + "simple_stmt", "var", "arith_expr", "term", "factor", YY_NULLPTR }; #endif @@ -539,11 +542,12 @@ static const char *const yytname[] = (internal) symbol number NUM (which must be that of a token). */ static const yytype_int16 yytoknum[] = { - 0, 256, 257, 258, 259, 260, 261, 262, 263 + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265 }; # endif -#define YYPACT_NINF (-11) +#define YYPACT_NINF (-14) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) @@ -557,9 +561,9 @@ static const yytype_int16 yytoknum[] = STATE-NUM. */ static const yytype_int8 yypact[] = { - 0, -2, -11, -11, 13, -11, 6, -11, -11, -1, - 4, -11, -11, -11, 8, 8, 8, 8, -11, -11, - -11, -11 + 0, -2, -14, -14, 13, -14, 4, -14, 8, -14, + -14, -14, 9, -14, -14, -1, 1, 9, 9, 9, + 9, -14, -14, -14, -14 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -567,21 +571,21 @@ static const yytype_int8 yypact[] = means the default is an error. */ static const yytype_int8 yydefact[] = { - 0, 0, 15, 4, 0, 3, 0, 7, 8, 11, - 14, 6, 1, 5, 0, 0, 0, 0, 9, 10, - 12, 13 + 0, 0, 9, 4, 0, 3, 0, 7, 0, 6, + 1, 5, 0, 16, 8, 12, 15, 0, 0, 0, + 0, 10, 11, 13, 14 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -11, -11, -11, -11, -11, -11, -10, -5 + -14, -14, -14, -14, -14, -14, -14, -13, -8 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 4, 5, 6, 7, 8, 9, 10 + -1, 4, 5, 6, 7, 8, 14, 15, 16 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -589,37 +593,37 @@ static const yytype_int8 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int8 yytable[] = { - -2, 1, 14, 15, 18, 19, 11, 2, 3, 16, - 17, 20, 21, 12, 13, 2 + -2, 1, 17, 18, 21, 22, 19, 20, 9, 2, + 3, 23, 24, 10, 11, 12, 0, 13 }; static const yytype_int8 yycheck[] = { - 0, 1, 3, 4, 14, 15, 8, 7, 8, 5, - 6, 16, 17, 0, 8, 7 + 0, 1, 3, 4, 17, 18, 5, 6, 10, 9, + 10, 19, 20, 0, 10, 7, -1, 8 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { - 0, 1, 7, 8, 10, 11, 12, 13, 14, 15, - 16, 8, 0, 8, 3, 4, 5, 6, 15, 15, - 16, 16 + 0, 1, 9, 10, 12, 13, 14, 15, 16, 10, + 0, 10, 7, 8, 17, 18, 19, 3, 4, 5, + 6, 18, 18, 19, 19 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_int8 yyr1[] = { - 0, 9, 10, 10, 11, 11, 11, 12, 13, 14, - 14, 14, 15, 15, 15, 16 + 0, 11, 12, 12, 13, 13, 13, 14, 15, 16, + 17, 17, 17, 18, 18, 18, 19 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_int8 yyr2[] = { - 0, 2, 0, 1, 1, 2, 2, 1, 1, 3, - 3, 1, 3, 3, 1, 1 + 0, 2, 0, 1, 1, 2, 2, 1, 3, 1, + 3, 3, 1, 3, 3, 1, 1 }; @@ -1315,85 +1319,91 @@ yyparse (void) switch (yyn) { case 2: -#line 34 "parser/cppython.y" - { create_empy_ast(); } -#line 1321 "parser/parser.c" +#line 37 "parser/cppython.y" + { create_empy_ast(); } +#line 1325 "parser/parser.c" break; case 4: -#line 38 "parser/cppython.y" - { create_empy_ast(); } -#line 1327 "parser/parser.c" +#line 41 "parser/cppython.y" + { create_empy_ast(); } +#line 1331 "parser/parser.c" break; case 5: -#line 39 "parser/cppython.y" - { create_ast((yyvsp[-1].expression)); } -#line 1333 "parser/parser.c" +#line 42 "parser/cppython.y" + { create_ast((yyvsp[-1].expression)); } +#line 1337 "parser/parser.c" break; case 6: -#line 40 "parser/cppython.y" - { yyerrok; } -#line 1339 "parser/parser.c" +#line 43 "parser/cppython.y" + { yyerrok; } +#line 1343 "parser/parser.c" break; case 7: -#line 43 "parser/cppython.y" - { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1345 "parser/parser.c" +#line 46 "parser/cppython.y" + { (yyval.expression) = print_exp((yyvsp[0].expression)); } +#line 1349 "parser/parser.c" break; case 8: -#line 45 "parser/cppython.y" - { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1351 "parser/parser.c" +#line 48 "parser/cppython.y" + { (yyval.expression) = create_bin_expr("=", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1355 "parser/parser.c" break; case 9: -#line 47 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("+", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1357 "parser/parser.c" +#line 50 "parser/cppython.y" + { (yyval.expression) = create_var_expr((yyvsp[0].var)); } +#line 1361 "parser/parser.c" break; case 10: -#line 48 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("-", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1363 "parser/parser.c" +#line 52 "parser/cppython.y" + { (yyval.expression) = create_bin_expr("+", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1367 "parser/parser.c" break; case 11: -#line 49 "parser/cppython.y" - { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1369 "parser/parser.c" +#line 53 "parser/cppython.y" + { (yyval.expression) = create_bin_expr("-", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1373 "parser/parser.c" break; case 12: -#line 52 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("*", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1375 "parser/parser.c" +#line 54 "parser/cppython.y" + { (yyval.expression) = print_exp((yyvsp[0].expression)); } +#line 1379 "parser/parser.c" break; case 13: -#line 53 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("/", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1381 "parser/parser.c" +#line 57 "parser/cppython.y" + { (yyval.expression) = create_bin_expr("*", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1385 "parser/parser.c" break; case 14: -#line 54 "parser/cppython.y" - { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1387 "parser/parser.c" +#line 58 "parser/cppython.y" + { (yyval.expression) = create_bin_expr("/", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1391 "parser/parser.c" break; case 15: -#line 57 "parser/cppython.y" - { (yyval.expression) = create_int_expr((yyvsp[0].value)); } -#line 1393 "parser/parser.c" +#line 59 "parser/cppython.y" + { (yyval.expression) = print_exp((yyvsp[0].expression)); } +#line 1397 "parser/parser.c" + break; + + case 16: +#line 62 "parser/cppython.y" + { (yyval.expression) = create_int_expr((yyvsp[0].int_value)); } +#line 1403 "parser/parser.c" break; -#line 1397 "parser/parser.c" +#line 1407 "parser/parser.c" default: break; } @@ -1625,7 +1635,7 @@ yyparse (void) #endif return yyresult; } -#line 60 "parser/cppython.y" +#line 65 "parser/cppython.y" void yyerror(const char *s) { diff --git a/src/parser/parser.h b/src/parser/parser.h index 103c50b..a9ac464 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -53,8 +53,10 @@ extern int yydebug; SUB = 259, MULT = 260, DIV = 261, - INTEGER = 262, - NEWLINE = 263 + ASSIGN = 262, + INTEGER = 263, + ID = 264, + NEWLINE = 265 }; #endif @@ -64,11 +66,12 @@ union YYSTYPE { #line 17 "parser/cppython.y" - int value; + int int_value; + char var[79]; char* op; ast_node* expression; -#line 72 "parser/parser.h" +#line 75 "parser/parser.h" }; typedef union YYSTYPE YYSTYPE; diff --git a/src/parser/parser.output b/src/parser/parser.output index ddbc938..ab4605a 100644 --- a/src/parser/parser.output +++ b/src/parser/parser.output @@ -11,56 +11,63 @@ Grammar 6 stmt: simple_stmt - 7 simple_stmt: arith_expr + 7 simple_stmt: var ASSIGN arith_expr - 8 arith_expr: term ADD term - 9 | term SUB term - 10 | term + 8 var: ID - 11 term: factor MULT factor - 12 | factor DIV factor - 13 | factor + 9 arith_expr: term ADD term + 10 | term SUB term + 11 | term - 14 factor: INTEGER + 12 term: factor MULT factor + 13 | factor DIV factor + 14 | factor + + 15 factor: INTEGER Terminals, with rules where they appear $end (0) 0 error (256) 5 - ADD (258) 8 - SUB (259) 9 - MULT (260) 11 - DIV (261) 12 - INTEGER (262) 14 - NEWLINE (263) 3 4 5 + ADD (258) 9 + SUB (259) 10 + MULT (260) 12 + DIV (261) 13 + ASSIGN (262) 7 + INTEGER (263) 15 + ID (264) 8 + NEWLINE (265) 3 4 5 Nonterminals, with rules where they appear - $accept (9) + $accept (11) on left: 0 - input (10) + input (12) on left: 1 2 on right: 0 - line (11) + line (13) on left: 3 4 5 on right: 2 - stmt (12) + stmt (14) on left: 6 on right: 4 - simple_stmt (13) + simple_stmt (15) on left: 7 on right: 6 - arith_expr (14) - on left: 8 9 10 + var (16) + on left: 8 + on right: 7 + arith_expr (17) + on left: 9 10 11 on right: 7 - term (15) - on left: 11 12 13 - on right: 8 9 10 - factor (16) - on left: 14 - on right: 11 12 13 + term (18) + on left: 12 13 14 + on right: 9 10 11 + factor (19) + on left: 15 + on right: 12 13 14 State 0 @@ -68,7 +75,7 @@ State 0 0 $accept: . input $end error shift, and go to state 1 - INTEGER shift, and go to state 2 + ID shift, and go to state 2 NEWLINE shift, and go to state 3 $end reduce using rule 1 (input) @@ -77,23 +84,21 @@ State 0 line go to state 5 stmt go to state 6 simple_stmt go to state 7 - arith_expr go to state 8 - term go to state 9 - factor go to state 10 + var go to state 8 State 1 5 line: error . NEWLINE - NEWLINE shift, and go to state 11 + NEWLINE shift, and go to state 9 State 2 - 14 factor: INTEGER . + 8 var: ID . - $default reduce using rule 14 (factor) + $default reduce using rule 8 (var) State 3 @@ -107,7 +112,7 @@ State 4 0 $accept: input . $end - $end shift, and go to state 12 + $end shift, and go to state 10 State 5 @@ -121,7 +126,7 @@ State 6 4 line: stmt . NEWLINE - NEWLINE shift, and go to state 13 + NEWLINE shift, and go to state 11 State 7 @@ -133,117 +138,142 @@ State 7 State 8 - 7 simple_stmt: arith_expr . + 7 simple_stmt: var . ASSIGN arith_expr - $default reduce using rule 7 (simple_stmt) + ASSIGN shift, and go to state 12 State 9 - 8 arith_expr: term . ADD term - 9 | term . SUB term - 10 | term . - - ADD shift, and go to state 14 - SUB shift, and go to state 15 + 5 line: error NEWLINE . - $default reduce using rule 10 (arith_expr) + $default reduce using rule 5 (line) State 10 - 11 term: factor . MULT factor - 12 | factor . DIV factor - 13 | factor . - - MULT shift, and go to state 16 - DIV shift, and go to state 17 + 0 $accept: input $end . - $default reduce using rule 13 (term) + $default accept State 11 - 5 line: error NEWLINE . + 4 line: stmt NEWLINE . - $default reduce using rule 5 (line) + $default reduce using rule 4 (line) State 12 - 0 $accept: input $end . + 7 simple_stmt: var ASSIGN . arith_expr - $default accept + INTEGER shift, and go to state 13 + + arith_expr go to state 14 + term go to state 15 + factor go to state 16 State 13 - 4 line: stmt NEWLINE . + 15 factor: INTEGER . - $default reduce using rule 4 (line) + $default reduce using rule 15 (factor) State 14 - 8 arith_expr: term ADD . term + 7 simple_stmt: var ASSIGN arith_expr . - INTEGER shift, and go to state 2 - - term go to state 18 - factor go to state 10 + $default reduce using rule 7 (simple_stmt) State 15 - 9 arith_expr: term SUB . term + 9 arith_expr: term . ADD term + 10 | term . SUB term + 11 | term . - INTEGER shift, and go to state 2 + ADD shift, and go to state 17 + SUB shift, and go to state 18 - term go to state 19 - factor go to state 10 + $default reduce using rule 11 (arith_expr) State 16 - 11 term: factor MULT . factor + 12 term: factor . MULT factor + 13 | factor . DIV factor + 14 | factor . - INTEGER shift, and go to state 2 + MULT shift, and go to state 19 + DIV shift, and go to state 20 - factor go to state 20 + $default reduce using rule 14 (term) State 17 - 12 term: factor DIV . factor + 9 arith_expr: term ADD . term - INTEGER shift, and go to state 2 + INTEGER shift, and go to state 13 - factor go to state 21 + term go to state 21 + factor go to state 16 State 18 - 8 arith_expr: term ADD term . + 10 arith_expr: term SUB . term + + INTEGER shift, and go to state 13 - $default reduce using rule 8 (arith_expr) + term go to state 22 + factor go to state 16 State 19 - 9 arith_expr: term SUB term . + 12 term: factor MULT . factor - $default reduce using rule 9 (arith_expr) + INTEGER shift, and go to state 13 + + factor go to state 23 State 20 - 11 term: factor MULT factor . + 13 term: factor DIV . factor + + INTEGER shift, and go to state 13 - $default reduce using rule 11 (term) + factor go to state 24 State 21 - 12 term: factor DIV factor . + 9 arith_expr: term ADD term . + + $default reduce using rule 9 (arith_expr) + + +State 22 + + 10 arith_expr: term SUB term . + + $default reduce using rule 10 (arith_expr) + + +State 23 + + 12 term: factor MULT factor . $default reduce using rule 12 (term) + + +State 24 + + 13 term: factor DIV factor . + + $default reduce using rule 13 (term) diff --git a/src/tests/parser/valid_1.ppy b/src/tests/parser/valid_1.ppy index a922b77..b372ec8 100644 --- a/src/tests/parser/valid_1.ppy +++ b/src/tests/parser/valid_1.ppy @@ -1 +1 @@ -2 + 2 +x = 2 + 2 From bf9d277e5fe40bcdca55454d05bd23ffb78b224c Mon Sep 17 00:00:00 2001 From: Dayanne Fernandes Date: Fri, 30 Oct 2020 02:18:05 -0300 Subject: [PATCH 07/10] create and print multiples ASTS --- src/core/ast.c | 36 ++++++++++++++++---- src/core/ast.h | 10 ++++-- src/core/main.c | 6 ++-- src/parser/cppython.y | 4 +-- src/parser/parser.c | 32 +++++++++--------- src/parser/parser.output | 65 ++++++++++++++++++------------------ src/tests/parser/valid_1.ppy | 3 +- 7 files changed, 94 insertions(+), 62 deletions(-) diff --git a/src/core/ast.c b/src/core/ast.c index 68a8882..591df90 100644 --- a/src/core/ast.c +++ b/src/core/ast.c @@ -30,15 +30,27 @@ ast_node* create_var_expr(char* value) { return expr; } -void create_ast(ast_node* expression) { +void add_ast(ast_node* expression) { if (PARSER_VERBOSE) printf("\nCreating AST.\n"); - root = expression; + if (ast_root == NULL) { + if (PARSER_VERBOSE) printf("First AST added.\n"); + ast_root = (ast_list*) malloc(sizeof(ast_list)); + ast_root->elem = expression; + ast_root->next = NULL; + } else { + ast_list* cur_ast = ast_root; + while (cur_ast->next != NULL) cur_ast = cur_ast->next; + ast_list* new_ast = (ast_list*) malloc(sizeof(ast_list)); + new_ast->elem = expression; + new_ast->next = NULL; + cur_ast->next = new_ast; + } return; } void create_empy_ast() { if (PARSER_VERBOSE) printf("\nCreating empty AST.\n"); - root = NULL; + ast_root = NULL; return; } @@ -50,12 +62,24 @@ ast_node* print_exp(ast_node* node) { return node; } -void print_ast(ast_node* node, int lvl) { - if (node == NULL) { +void print_asts(ast_list* root) { + if (root == NULL) { printf("Empty AST.\n"); return; } - + + ast_list* cur_ast = root; + int ast_idx = 0; + + while (cur_ast != NULL) { + printf("\n\n---- AST: %d\n\n", ast_idx + 1); + print_ast(cur_ast->elem, 0); + cur_ast = cur_ast->next; + ast_idx += 1; + } +} + +void print_ast(ast_node* node, int lvl) { if (PARSER_VERBOSE) printf("TAG: %d\n", node->tag); for (int i=0; i < lvl; ++i) printf(" "); diff --git a/src/core/ast.h b/src/core/ast.h index b66f05d..9bf444d 100644 --- a/src/core/ast.h +++ b/src/core/ast.h @@ -23,13 +23,19 @@ typedef struct exp { } op; } ast_node; -ast_node* root; +typedef struct exps { + ast_node* elem; + struct exps* next; +} ast_list; +ast_list* ast_root; + +void print_asts(ast_list* root); void print_ast(ast_node* node, int lvl); ast_node* print_exp(ast_node* node); void create_empy_ast(); -void create_ast(ast_node* expression); +void add_ast(ast_node* expression); ast_node* create_int_expr(int value); ast_node* create_var_expr(char* value); ast_node* create_bin_expr(char* operator, ast_node* left, ast_node* right); diff --git a/src/core/main.c b/src/core/main.c index d789972..11a53fb 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -7,7 +7,7 @@ int main (int argc, char* argv[]) { printf("Welcome to CPPython interpreter:\n"); MAIN_VERBOSE = LEX_VERBOSE = PARSER_VERBOSE = 0; - root = NULL; + ast_root = NULL; // init lexer and parser printf("Lexer/parser:\n"); @@ -20,8 +20,8 @@ int main (int argc, char* argv[]) { fclose(yyin); printf("\nLexer and parser finished.\n\n"); - printf("Abstract Syntax Tree:\n"); - print_ast(root, 0); + printf("Abstract Syntax Trees:"); + print_asts(ast_root); printf("\nSymbol Table:\n"); print_st(); diff --git a/src/parser/cppython.y b/src/parser/cppython.y index 10de57f..db52ae8 100644 --- a/src/parser/cppython.y +++ b/src/parser/cppython.y @@ -35,11 +35,11 @@ %% input : /* empty */ { create_empy_ast(); } - | line + | input line line : NEWLINE { create_empy_ast(); } - | stmt[U] NEWLINE { create_ast($U); } + | stmt[U] NEWLINE { add_ast($U); } | error NEWLINE { yyerrok; } ; diff --git a/src/parser/parser.c b/src/parser/parser.c index 3ef6bf7..96b1920 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -462,9 +462,9 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 10 +#define YYFINAL 2 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 17 +#define YYLAST 16 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 11 @@ -552,7 +552,7 @@ static const yytype_int16 yytoknum[] = #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) -#define YYTABLE_NINF (-3) +#define YYTABLE_NINF (-1) #define yytable_value_is_error(Yyn) \ 0 @@ -561,9 +561,9 @@ static const yytype_int16 yytoknum[] = STATE-NUM. */ static const yytype_int8 yypact[] = { - 0, -2, -14, -14, 13, -14, 4, -14, 8, -14, - -14, -14, 9, -14, -14, -1, 1, 9, 9, 9, - 9, -14, -14, -14, -14 + -14, 0, -14, -2, -14, -14, -14, 3, -14, 7, + -14, -14, 8, -14, -14, -1, 1, 8, 8, 8, + 8, -14, -14, -14, -14 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -571,8 +571,8 @@ static const yytype_int8 yypact[] = means the default is an error. */ static const yytype_int8 yydefact[] = { - 0, 0, 9, 4, 0, 3, 0, 7, 0, 6, - 1, 5, 0, 16, 8, 12, 15, 0, 0, 0, + 2, 0, 1, 0, 9, 4, 3, 0, 7, 0, + 6, 5, 0, 16, 8, 12, 15, 0, 0, 0, 0, 10, 11, 13, 14 }; @@ -585,7 +585,7 @@ static const yytype_int8 yypgoto[] = /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 4, 5, 6, 7, 8, 14, 15, 16 + -1, 1, 6, 7, 8, 9, 14, 15, 16 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -593,22 +593,22 @@ static const yytype_int8 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int8 yytable[] = { - -2, 1, 17, 18, 21, 22, 19, 20, 9, 2, - 3, 23, 24, 10, 11, 12, 0, 13 + 2, 3, 17, 18, 21, 22, 19, 20, 10, 4, + 5, 23, 24, 11, 12, 0, 13 }; static const yytype_int8 yycheck[] = { 0, 1, 3, 4, 17, 18, 5, 6, 10, 9, - 10, 19, 20, 0, 10, 7, -1, 8 + 10, 19, 20, 10, 7, -1, 8 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { - 0, 1, 9, 10, 12, 13, 14, 15, 16, 10, - 0, 10, 7, 8, 17, 18, 19, 3, 4, 5, + 0, 12, 0, 1, 9, 10, 13, 14, 15, 16, + 10, 10, 7, 8, 17, 18, 19, 3, 4, 5, 6, 18, 18, 19, 19 }; @@ -622,7 +622,7 @@ static const yytype_int8 yyr1[] = /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_int8 yyr2[] = { - 0, 2, 0, 1, 1, 2, 2, 1, 3, 1, + 0, 2, 0, 2, 1, 2, 2, 1, 3, 1, 3, 3, 1, 3, 3, 1, 1 }; @@ -1332,7 +1332,7 @@ yyparse (void) case 5: #line 42 "parser/cppython.y" - { create_ast((yyvsp[-1].expression)); } + { add_ast((yyvsp[-1].expression)); } #line 1337 "parser/parser.c" break; diff --git a/src/parser/parser.output b/src/parser/parser.output index ab4605a..980c61e 100644 --- a/src/parser/parser.output +++ b/src/parser/parser.output @@ -3,7 +3,7 @@ Grammar 0 $accept: input $end 1 input: %empty - 2 | line + 2 | input line 3 line: NEWLINE 4 | stmt NEWLINE @@ -46,7 +46,7 @@ Nonterminals, with rules where they appear on left: 0 input (12) on left: 1 2 - on right: 0 + on right: 0 2 line (13) on left: 3 4 5 on right: 2 @@ -74,87 +74,88 @@ State 0 0 $accept: . input $end - error shift, and go to state 1 - ID shift, and go to state 2 - NEWLINE shift, and go to state 3 + $default reduce using rule 1 (input) - $end reduce using rule 1 (input) - - input go to state 4 - line go to state 5 - stmt go to state 6 - simple_stmt go to state 7 - var go to state 8 + input go to state 1 State 1 - 5 line: error . NEWLINE + 0 $accept: input . $end + 2 input: input . line - NEWLINE shift, and go to state 9 + $end shift, and go to state 2 + error shift, and go to state 3 + ID shift, and go to state 4 + NEWLINE shift, and go to state 5 + + line go to state 6 + stmt go to state 7 + simple_stmt go to state 8 + var go to state 9 State 2 - 8 var: ID . + 0 $accept: input $end . - $default reduce using rule 8 (var) + $default accept State 3 - 3 line: NEWLINE . + 5 line: error . NEWLINE - $default reduce using rule 3 (line) + NEWLINE shift, and go to state 10 State 4 - 0 $accept: input . $end + 8 var: ID . - $end shift, and go to state 10 + $default reduce using rule 8 (var) State 5 - 2 input: line . + 3 line: NEWLINE . - $default reduce using rule 2 (input) + $default reduce using rule 3 (line) State 6 - 4 line: stmt . NEWLINE + 2 input: input line . - NEWLINE shift, and go to state 11 + $default reduce using rule 2 (input) State 7 - 6 stmt: simple_stmt . + 4 line: stmt . NEWLINE - $default reduce using rule 6 (stmt) + NEWLINE shift, and go to state 11 State 8 - 7 simple_stmt: var . ASSIGN arith_expr + 6 stmt: simple_stmt . - ASSIGN shift, and go to state 12 + $default reduce using rule 6 (stmt) State 9 - 5 line: error NEWLINE . + 7 simple_stmt: var . ASSIGN arith_expr - $default reduce using rule 5 (line) + ASSIGN shift, and go to state 12 State 10 - 0 $accept: input $end . + 5 line: error NEWLINE . - $default accept + $default reduce using rule 5 (line) State 11 diff --git a/src/tests/parser/valid_1.ppy b/src/tests/parser/valid_1.ppy index b372ec8..2c18545 100644 --- a/src/tests/parser/valid_1.ppy +++ b/src/tests/parser/valid_1.ppy @@ -1 +1,2 @@ -x = 2 + 2 +x = 1 +y = 2 From 8a64df8550bb833fef2f35aa5d1300ac17348908 Mon Sep 17 00:00:00 2001 From: Dayanne Fernandes Date: Fri, 30 Oct 2020 02:25:17 -0300 Subject: [PATCH 08/10] symbol table --- src/core/ast.h | 1 + src/core/main.c | 4 ++-- src/core/sym_tab.c | 10 +++++++--- src/lexer/cppython.lex | 1 + src/lexer/lexer.c | 1 + src/tests/parser/valid_1.ppy | 1 + 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/core/ast.h b/src/core/ast.h index 9bf444d..11611c9 100644 --- a/src/core/ast.h +++ b/src/core/ast.h @@ -30,6 +30,7 @@ typedef struct exps { ast_list* ast_root; +int len_st(); void print_asts(ast_list* root); void print_ast(ast_node* node, int lvl); ast_node* print_exp(ast_node* node); diff --git a/src/core/main.c b/src/core/main.c index 11a53fb..a9821f8 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -20,10 +20,10 @@ int main (int argc, char* argv[]) { fclose(yyin); printf("\nLexer and parser finished.\n\n"); - printf("Abstract Syntax Trees:"); + printf("## Abstract Syntax Trees ##"); print_asts(ast_root); - printf("\nSymbol Table:\n"); + printf("\n## Symbol Table ##\n"); print_st(); return 0; diff --git a/src/core/sym_tab.c b/src/core/sym_tab.c index ea6b37c..e199307 100644 --- a/src/core/sym_tab.c +++ b/src/core/sym_tab.c @@ -32,19 +32,23 @@ void delete_all() { } } +int len_st() { + return HASH_COUNT(symbol_table); +} + void print_st() { - unsigned int num_symbols = HASH_COUNT(symbol_table); + int num_symbols = HASH_COUNT(symbol_table); if (num_symbols == 0) { printf("Empty symbol table.\n"); return; } - printf("Size: %u\n", num_symbols); + printf("Size: %u\n\n", num_symbols); word* cur_word, *tmp; HASH_ITER(hh, symbol_table, cur_word, tmp) { - printf("KEY: %d, NAME: %s", cur_word->key, cur_word->name); + printf("KEY: %d, NAME: %s\n", cur_word->key, cur_word->name); HASH_DEL(symbol_table, cur_word); free(cur_word); } diff --git a/src/lexer/cppython.lex b/src/lexer/cppython.lex index 96e8551..75d04e7 100644 --- a/src/lexer/cppython.lex +++ b/src/lexer/cppython.lex @@ -124,6 +124,7 @@ void handle_token(int token) { break; case ID_TOK: if (LEX_VERBOSE) printf("Token: ", yytext); + add_word(len_st(), yytext); strcpy(yylval.var, yytext); break; case ASSIGN_TOK: diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index af8d7d7..44dff24 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -1950,6 +1950,7 @@ void handle_token(int token) { break; case ID_TOK: if (LEX_VERBOSE) printf("Token: ", yytext); + add_word(len_st(), yytext); strcpy(yylval.var, yytext); break; case ASSIGN_TOK: diff --git a/src/tests/parser/valid_1.ppy b/src/tests/parser/valid_1.ppy index 2c18545..0b3f4bd 100644 --- a/src/tests/parser/valid_1.ppy +++ b/src/tests/parser/valid_1.ppy @@ -1,2 +1,3 @@ x = 1 y = 2 +z = 5 + 5 / 9 From a192c1efeae0b75ca27690d46ba87fa93feab442 Mon Sep 17 00:00:00 2001 From: Dayanne Fernandes Date: Fri, 30 Oct 2020 03:26:36 -0300 Subject: [PATCH 09/10] fix arithm and assign grammar rules --- src/core/ast.c | 2 +- src/parser/cppython.y | 17 ++++++---- src/parser/parser.c | 64 ++++++++++++++++++++---------------- src/parser/parser.output | 60 +++++++++++++++++++-------------- src/tests/parser/valid_1.ppy | 6 ++-- 5 files changed, 84 insertions(+), 65 deletions(-) diff --git a/src/core/ast.c b/src/core/ast.c index 591df90..f0c84d0 100644 --- a/src/core/ast.c +++ b/src/core/ast.c @@ -64,7 +64,7 @@ ast_node* print_exp(ast_node* node) { void print_asts(ast_list* root) { if (root == NULL) { - printf("Empty AST.\n"); + printf("\nEmpty AST.\n"); return; } diff --git a/src/parser/cppython.y b/src/parser/cppython.y index db52ae8..dc730ee 100644 --- a/src/parser/cppython.y +++ b/src/parser/cppython.y @@ -35,8 +35,8 @@ %% input : /* empty */ { create_empy_ast(); } - | input line - + | input line { ; } + ; line : NEWLINE { create_empy_ast(); } | stmt[U] NEWLINE { add_ast($U); } @@ -44,18 +44,21 @@ line : NEWLINE { create_empy_ast(); } ; stmt : simple_stmt[U] { $$ = print_exp($U); } + ; simple_stmt : var[L] ASSIGN arith_expr[R] { $$ = create_bin_expr("=", $L, $R); } + ; -var : ID[U] { $$ = create_var_expr($U); } +var : ID[U] { $$ = create_var_expr($U); } + ; -arith_expr : term[L] ADD term[R] { $$ = create_bin_expr("+", $L, $R); } - | term[L] SUB term[R] { $$ = create_bin_expr("-", $L, $R); } +arith_expr : arith_expr[L] ADD term[R] { $$ = create_bin_expr("+", $L, $R); } + | arith_expr[L] SUB term[R] { $$ = create_bin_expr("-", $L, $R); } | term[U] { $$ = print_exp($U); } ; -term : factor[L] MULT factor[R] { $$ = create_bin_expr("*", $L, $R); } - | factor[L] DIV factor[R] { $$ = create_bin_expr("/", $L, $R); } +term : term[L] MULT factor[R] { $$ = create_bin_expr("*", $L, $R); } + | term[L] DIV factor[R] { $$ = create_bin_expr("/", $L, $R); } | factor[U] { $$ = print_exp($U); } ; diff --git a/src/parser/parser.c b/src/parser/parser.c index 96b1920..b880e20 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -521,8 +521,8 @@ static const yytype_int8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int8 yyrline[] = { - 0, 37, 37, 38, 41, 42, 43, 46, 48, 50, - 52, 53, 54, 57, 58, 59, 62 + 0, 37, 37, 38, 41, 42, 43, 46, 49, 52, + 55, 56, 57, 60, 61, 62, 65 }; #endif @@ -562,8 +562,8 @@ static const yytype_int16 yytoknum[] = static const yytype_int8 yypact[] = { -14, 0, -14, -2, -14, -14, -14, 3, -14, 7, - -14, -14, 8, -14, -14, -1, 1, 8, 8, 8, - 8, -14, -14, -14, -14 + -14, -14, 8, -14, -1, 1, -14, 8, 8, 8, + 8, 1, 1, -14, -14 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -1324,86 +1324,92 @@ yyparse (void) #line 1325 "parser/parser.c" break; + case 3: +#line 38 "parser/cppython.y" + { ; } +#line 1331 "parser/parser.c" + break; + case 4: #line 41 "parser/cppython.y" { create_empy_ast(); } -#line 1331 "parser/parser.c" +#line 1337 "parser/parser.c" break; case 5: #line 42 "parser/cppython.y" { add_ast((yyvsp[-1].expression)); } -#line 1337 "parser/parser.c" +#line 1343 "parser/parser.c" break; case 6: #line 43 "parser/cppython.y" { yyerrok; } -#line 1343 "parser/parser.c" +#line 1349 "parser/parser.c" break; case 7: #line 46 "parser/cppython.y" { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1349 "parser/parser.c" +#line 1355 "parser/parser.c" break; case 8: -#line 48 "parser/cppython.y" +#line 49 "parser/cppython.y" { (yyval.expression) = create_bin_expr("=", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1355 "parser/parser.c" +#line 1361 "parser/parser.c" break; case 9: -#line 50 "parser/cppython.y" - { (yyval.expression) = create_var_expr((yyvsp[0].var)); } -#line 1361 "parser/parser.c" +#line 52 "parser/cppython.y" + { (yyval.expression) = create_var_expr((yyvsp[0].var)); } +#line 1367 "parser/parser.c" break; case 10: -#line 52 "parser/cppython.y" +#line 55 "parser/cppython.y" { (yyval.expression) = create_bin_expr("+", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1367 "parser/parser.c" +#line 1373 "parser/parser.c" break; case 11: -#line 53 "parser/cppython.y" +#line 56 "parser/cppython.y" { (yyval.expression) = create_bin_expr("-", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1373 "parser/parser.c" +#line 1379 "parser/parser.c" break; case 12: -#line 54 "parser/cppython.y" +#line 57 "parser/cppython.y" { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1379 "parser/parser.c" +#line 1385 "parser/parser.c" break; case 13: -#line 57 "parser/cppython.y" +#line 60 "parser/cppython.y" { (yyval.expression) = create_bin_expr("*", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1385 "parser/parser.c" +#line 1391 "parser/parser.c" break; case 14: -#line 58 "parser/cppython.y" +#line 61 "parser/cppython.y" { (yyval.expression) = create_bin_expr("/", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1391 "parser/parser.c" +#line 1397 "parser/parser.c" break; case 15: -#line 59 "parser/cppython.y" +#line 62 "parser/cppython.y" { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1397 "parser/parser.c" +#line 1403 "parser/parser.c" break; case 16: -#line 62 "parser/cppython.y" +#line 65 "parser/cppython.y" { (yyval.expression) = create_int_expr((yyvsp[0].int_value)); } -#line 1403 "parser/parser.c" +#line 1409 "parser/parser.c" break; -#line 1407 "parser/parser.c" +#line 1413 "parser/parser.c" default: break; } @@ -1635,7 +1641,7 @@ yyparse (void) #endif return yyresult; } -#line 65 "parser/cppython.y" +#line 68 "parser/cppython.y" void yyerror(const char *s) { diff --git a/src/parser/parser.output b/src/parser/parser.output index 980c61e..1ac5eac 100644 --- a/src/parser/parser.output +++ b/src/parser/parser.output @@ -15,12 +15,12 @@ Grammar 8 var: ID - 9 arith_expr: term ADD term - 10 | term SUB term + 9 arith_expr: arith_expr ADD term + 10 | arith_expr SUB term 11 | term - 12 term: factor MULT factor - 13 | factor DIV factor + 12 term: term MULT factor + 13 | term DIV factor 14 | factor 15 factor: INTEGER @@ -61,10 +61,10 @@ Nonterminals, with rules where they appear on right: 7 arith_expr (17) on left: 9 10 11 - on right: 7 + on right: 7 9 10 term (18) on left: 12 13 14 - on right: 9 10 11 + on right: 9 10 11 12 13 factor (19) on left: 15 on right: 12 13 14 @@ -186,37 +186,37 @@ State 13 State 14 7 simple_stmt: var ASSIGN arith_expr . + 9 arith_expr: arith_expr . ADD term + 10 | arith_expr . SUB term + + ADD shift, and go to state 17 + SUB shift, and go to state 18 $default reduce using rule 7 (simple_stmt) State 15 - 9 arith_expr: term . ADD term - 10 | term . SUB term - 11 | term . + 11 arith_expr: term . + 12 term: term . MULT factor + 13 | term . DIV factor - ADD shift, and go to state 17 - SUB shift, and go to state 18 + MULT shift, and go to state 19 + DIV shift, and go to state 20 $default reduce using rule 11 (arith_expr) State 16 - 12 term: factor . MULT factor - 13 | factor . DIV factor - 14 | factor . - - MULT shift, and go to state 19 - DIV shift, and go to state 20 + 14 term: factor . $default reduce using rule 14 (term) State 17 - 9 arith_expr: term ADD . term + 9 arith_expr: arith_expr ADD . term INTEGER shift, and go to state 13 @@ -226,7 +226,7 @@ State 17 State 18 - 10 arith_expr: term SUB . term + 10 arith_expr: arith_expr SUB . term INTEGER shift, and go to state 13 @@ -236,7 +236,7 @@ State 18 State 19 - 12 term: factor MULT . factor + 12 term: term MULT . factor INTEGER shift, and go to state 13 @@ -245,7 +245,7 @@ State 19 State 20 - 13 term: factor DIV . factor + 13 term: term DIV . factor INTEGER shift, and go to state 13 @@ -254,27 +254,37 @@ State 20 State 21 - 9 arith_expr: term ADD term . + 9 arith_expr: arith_expr ADD term . + 12 term: term . MULT factor + 13 | term . DIV factor + + MULT shift, and go to state 19 + DIV shift, and go to state 20 $default reduce using rule 9 (arith_expr) State 22 - 10 arith_expr: term SUB term . + 10 arith_expr: arith_expr SUB term . + 12 term: term . MULT factor + 13 | term . DIV factor + + MULT shift, and go to state 19 + DIV shift, and go to state 20 $default reduce using rule 10 (arith_expr) State 23 - 12 term: factor MULT factor . + 12 term: term MULT factor . $default reduce using rule 12 (term) State 24 - 13 term: factor DIV factor . + 13 term: term DIV factor . $default reduce using rule 13 (term) diff --git a/src/tests/parser/valid_1.ppy b/src/tests/parser/valid_1.ppy index 0b3f4bd..0f0cdf2 100644 --- a/src/tests/parser/valid_1.ppy +++ b/src/tests/parser/valid_1.ppy @@ -1,3 +1,3 @@ -x = 1 -y = 2 -z = 5 + 5 / 9 +x = 5 + 2 - 1 / 9 +z = 4 + 4 * 2 * 5 - 3 / 0 +w = 9 From 069bdc7cdc1a0496a849b46a9e69c1a0d88a4dbc Mon Sep 17 00:00:00 2001 From: Dayanne Fernandes Date: Fri, 30 Oct 2020 04:33:47 -0300 Subject: [PATCH 10/10] arithm expr completed and booleans --- src/core/ast.c | 24 ++++ src/core/ast.h | 5 + src/lexer/cppython.lex | 25 ++-- src/lexer/lexer.c | 217 +++++++++++++++++---------------- src/lexer/lexer.h | 2 +- src/parser/cppython.y | 27 ++-- src/parser/parser.c | 168 ++++++++++++++----------- src/parser/parser.h | 9 +- src/parser/parser.output | 203 +++++++++++++++++------------- src/tests/parser/invalid_1.ppy | 8 +- src/tests/parser/valid_2.ppy | 7 +- 11 files changed, 408 insertions(+), 287 deletions(-) diff --git a/src/core/ast.c b/src/core/ast.c index f0c84d0..90dfb7e 100644 --- a/src/core/ast.c +++ b/src/core/ast.c @@ -22,6 +22,22 @@ ast_node* create_int_expr(int value) { return expr; } +ast_node* create_float_expr(float value) { + if (PARSER_VERBOSE) printf("\n\nCreating float expression node: %f\n", value); + ast_node* expr = (ast_node*) malloc(sizeof(ast_node)); + expr->tag = FLOAT_TYPE; + expr->op.float_expr = value; + return expr; +} + +ast_node* create_bool_expr(int value) { + if (PARSER_VERBOSE) printf("\n\nCreating boolean expression node: %d\n", value); + ast_node* expr = (ast_node*) malloc(sizeof(ast_node)); + expr->tag = BOOL_TYPE; + expr->op.integer_expr = value; + return expr; +} + ast_node* create_var_expr(char* value) { if (PARSER_VERBOSE) printf("\n\nCreating variable expression node: %s\n", value); ast_node* expr = (ast_node*) malloc(sizeof(ast_node)); @@ -89,6 +105,14 @@ void print_ast(ast_node* node, int lvl) { printf("INT: %d\n", node->op.integer_expr); return; // terminal leaf + } else if (node->tag == BOOL_TYPE) { + printf("BOOL: %d\n", node->op.integer_expr); + return; + // terminal leaf + } else if (node->tag == FLOAT_TYPE) { + printf("FLOAT: %.2f\n", node->op.float_expr); + return; + // terminal leaf } else if (node->tag == VAR_TYPE) { printf("VAR: %s\n", node->op.variable_expr); return; diff --git a/src/core/ast.h b/src/core/ast.h index 11611c9..e93d608 100644 --- a/src/core/ast.h +++ b/src/core/ast.h @@ -6,6 +6,8 @@ int lex_line, lex_column, parser_line, parser_column; enum TAG { INTEGER_TYPE=0, + FLOAT_TYPE, + BOOL_TYPE, VAR_TYPE, BINARY_TYPE }; @@ -14,6 +16,7 @@ typedef struct exp { int tag; union { int integer_expr; + float float_expr; char variable_expr[79]; struct { char* operator; @@ -38,7 +41,9 @@ ast_node* print_exp(ast_node* node); void create_empy_ast(); void add_ast(ast_node* expression); ast_node* create_int_expr(int value); +ast_node* create_float_expr(float value); ast_node* create_var_expr(char* value); +ast_node* create_bool_expr(int value); ast_node* create_bin_expr(char* operator, ast_node* left, ast_node* right); void handle_token(int token); diff --git a/src/lexer/cppython.lex b/src/lexer/cppython.lex index 75d04e7..c1981fd 100644 --- a/src/lexer/cppython.lex +++ b/src/lexer/cppython.lex @@ -30,9 +30,7 @@ %} %option outfile="lexer/lexer.c" header-file="lexer/lexer.h" -%option nounput -%option noinput -%option yylineno +%option nounput noinput yylineno /* regex and token definition */ @@ -43,19 +41,17 @@ SUB ("-") ADD ("+") MULT ("*") DIV ("/") -OPERATOR (ADD|SUB|MULT|DIV) BOOLEAN_OP ("=="|"<="|">="|"!="|"<"|">"|"~"|"|"|"&"|"and"|"or"|"not") ASSIGN ("=") DELIMITER ("("|")"|"["|"]"|";"|","|"."|":") -BOOLEAN ("True"|"False") -NULL ("None") +BOOLEAN (True|False) +NULL (None) NEWLINE (\n) WHITESPACE ([ \t]+) VAR ({LETTER}|"_")({LETTER}|{DIGIT}|"_")* STRING (\".*\"|\'.*\') INTEGER ({NDIGIT}{DIGIT}*|"0") -FLOAT ([{DIGIT}+]"."{DIGIT}+|{DIGIT}+".") -NUMBER ({INTEGER}|{FLOAT}) +FLOAT ({DIGIT}+\.{DIGIT}+) %% @@ -65,8 +61,8 @@ NUMBER ({INTEGER}|{FLOAT}) /* arithmetic expressions */ +{FLOAT} { handle_token(FLOAT_TOK); return FLOAT; }; {INTEGER} { handle_token(INTEGER_TOK); return INTEGER; }; -{FLOAT} ; {SUB} { handle_token(SUB_TOK); return SUB; }; {ADD} { handle_token(ADD_TOK); return ADD; }; {MULT} { handle_token(MULT_TOK); return MULT; }; @@ -76,7 +72,7 @@ NUMBER ({INTEGER}|{FLOAT}) /* conditional and booleans expressions */ -{BOOLEAN} ; +{BOOLEAN} { handle_token(BOOLEAN_TOK); return BOOLEAN; }; {BOOLEAN_OP} ; /* structure helpers */ @@ -102,10 +98,19 @@ NUMBER ({INTEGER}|{FLOAT}) void handle_token(int token) { parser_column = lex_column; switch (token) { + case BOOLEAN_TOK: + if (LEX_VERBOSE) printf("Token: ", yytext); + if (strcmp(yytext, "True") == 0) yylval.int_value = 1; + else if (strcmp(yytext, "False") == 0) yylval.int_value = 0; + break; case INTEGER_TOK: if (LEX_VERBOSE) printf("Token: ", yytext); yylval.int_value = atoi(yytext); break; + case FLOAT_TOK: + if (LEX_VERBOSE) printf("Token: ", yytext); + yylval.float_value = atof(yytext); + break; case SUB_TOK: if (LEX_VERBOSE) printf("Token: ", yytext); yylval.op = yytext; diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index 44dff24..73d30f9 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -380,16 +380,16 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static const flex_int16_t yy_accept[80] = +static const flex_int16_t yy_accept[77] = { 0, 0, 0, 19, 17, 15, 14, 17, 17, 17, 11, - 17, 9, 6, 5, 4, 7, 2, 2, 11, 8, + 17, 9, 6, 5, 4, 7, 3, 3, 11, 8, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 17, 15, 11, 0, 13, - 0, 12, 0, 13, 0, 3, 0, 2, 16, 16, - 16, 16, 16, 16, 16, 1, 16, 16, 11, 16, - 16, 16, 3, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 10, 16, 16, 16, 16, 16, 0 + 16, 16, 16, 16, 15, 11, 0, 13, 0, 12, + 0, 13, 0, 0, 3, 16, 16, 16, 16, 16, + 16, 16, 1, 16, 16, 11, 16, 16, 16, 2, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 10, + 16, 16, 16, 16, 16, 0 } ; static const YY_CHAR yy_ec[256] = @@ -400,14 +400,14 @@ static const YY_CHAR yy_ec[256] = 1, 2, 4, 5, 6, 1, 1, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, - 22, 23, 1, 1, 24, 24, 24, 25, 24, 26, - 25, 24, 25, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 27, 24, 24, 24, 24, 24, 24, - 28, 1, 29, 1, 30, 1, 31, 24, 24, 32, - - 33, 34, 24, 35, 36, 24, 24, 37, 24, 38, - 39, 40, 24, 41, 42, 43, 44, 24, 45, 24, - 24, 24, 46, 47, 46, 48, 1, 1, 1, 1, + 22, 23, 1, 1, 24, 24, 24, 24, 24, 25, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 26, 24, 24, 24, 24, 24, 24, + 27, 1, 28, 1, 29, 1, 30, 24, 24, 31, + + 32, 33, 24, 34, 35, 24, 24, 36, 24, 37, + 38, 39, 24, 40, 41, 42, 43, 24, 44, 24, + 24, 24, 1, 45, 1, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -424,85 +424,83 @@ static const YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1 } ; -static const YY_CHAR yy_meta[49] = +static const YY_CHAR yy_meta[47] = { 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, - 1, 1, 1, 3, 3, 3, 3, 1, 1, 3, + 1, 1, 1, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 1, 1, 1 + 3, 3, 3, 3, 1, 1 } ; -static const flex_int16_t yy_base[84] = +static const flex_int16_t yy_base[81] = { 0, - 0, 0, 130, 131, 127, 131, 106, 122, 123, 131, - 117, 131, 131, 109, 131, 131, 34, 38, 101, 100, - 99, 0, 105, 88, 35, 80, 84, 79, 76, 20, - 75, 72, 71, 78, 75, 94, 106, 131, 102, 101, - 102, 131, 96, 95, 42, 131, 46, 50, 0, 65, - 57, 68, 65, 30, 57, 0, 57, 53, 0, 59, - 51, 57, 52, 50, 58, 56, 56, 44, 49, 42, - 47, 45, 0, 32, 31, 32, 38, 24, 131, 76, - 79, 82, 54 + 0, 0, 124, 125, 121, 125, 100, 116, 117, 125, + 111, 125, 125, 125, 125, 125, 32, 36, 96, 95, + 94, 0, 85, 74, 76, 80, 75, 72, 15, 71, + 68, 67, 74, 71, 102, 125, 98, 97, 98, 125, + 92, 91, 38, 42, 46, 0, 62, 54, 65, 62, + 27, 54, 0, 54, 50, 0, 56, 48, 54, 48, + 47, 55, 53, 53, 41, 46, 39, 45, 48, 0, + 37, 36, 36, 38, 30, 125, 68, 71, 74, 55 } ; -static const flex_int16_t yy_def[84] = +static const flex_int16_t yy_def[81] = { 0, - 79, 1, 79, 79, 79, 79, 79, 80, 81, 79, - 82, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 79, 79, 79, 80, 80, - 81, 79, 82, 82, 79, 79, 79, 79, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 79, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 0, 79, - 79, 79, 79 + 76, 1, 76, 76, 76, 76, 76, 77, 78, 76, + 79, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 76, 76, 77, 77, 78, 76, + 79, 79, 76, 76, 76, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 76, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 0, 76, 76, 76, 76 } ; -static const flex_int16_t yy_nxt[180] = +static const flex_int16_t yy_nxt[172] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 14, 12, 15, 12, 16, 17, 18, 12, 12, - 19, 20, 21, 22, 23, 24, 25, 12, 12, 22, - 26, 27, 28, 29, 22, 30, 22, 31, 32, 33, - 34, 22, 22, 22, 35, 36, 10, 10, 46, 45, - 47, 47, 46, 56, 48, 48, 49, 57, 63, 63, - 46, 56, 47, 47, 46, 66, 48, 48, 63, 63, - 56, 67, 78, 56, 56, 51, 39, 73, 39, 41, - 41, 41, 43, 77, 43, 76, 75, 74, 56, 56, - 73, 72, 71, 70, 69, 59, 68, 56, 56, 59, - - 65, 64, 44, 44, 42, 40, 40, 37, 45, 62, - 61, 60, 59, 58, 55, 54, 53, 52, 50, 45, - 38, 38, 38, 45, 44, 42, 40, 38, 37, 79, - 3, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79 + 19, 20, 21, 22, 23, 24, 12, 12, 22, 25, + 26, 27, 28, 22, 29, 22, 30, 31, 32, 33, + 22, 22, 22, 34, 10, 10, 43, 53, 44, 44, + 43, 54, 45, 45, 60, 60, 43, 46, 44, 44, + 43, 63, 45, 45, 60, 60, 53, 64, 37, 53, + 37, 39, 39, 39, 41, 75, 41, 53, 53, 70, + 74, 73, 72, 71, 53, 53, 70, 69, 68, 67, + 66, 56, 65, 53, 53, 56, 62, 61, 42, 42, + + 40, 38, 38, 35, 59, 58, 57, 56, 55, 52, + 51, 50, 49, 48, 47, 36, 36, 36, 42, 40, + 38, 36, 35, 76, 3, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76 } ; -static const flex_int16_t yy_chk[180] = +static const flex_int16_t yy_chk[172] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 17, 25, - 17, 17, 18, 30, 18, 18, 83, 30, 45, 45, - 47, 78, 47, 47, 48, 54, 48, 48, 63, 63, - 77, 54, 76, 75, 74, 25, 80, 72, 80, 81, - 81, 81, 82, 71, 82, 70, 69, 68, 67, 66, - 65, 64, 62, 61, 60, 58, 57, 55, 53, 52, - - 51, 50, 44, 43, 41, 40, 39, 37, 36, 35, - 34, 33, 32, 31, 29, 28, 27, 26, 24, 23, - 21, 20, 19, 14, 11, 9, 8, 7, 5, 3, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79 + 1, 1, 1, 1, 1, 1, 17, 29, 17, 17, + 18, 29, 18, 18, 43, 43, 44, 80, 44, 44, + 45, 51, 45, 45, 60, 60, 75, 51, 77, 74, + 77, 78, 78, 78, 79, 73, 79, 72, 71, 69, + 68, 67, 66, 65, 64, 63, 62, 61, 59, 58, + 57, 55, 54, 52, 50, 49, 48, 47, 42, 41, + + 39, 38, 37, 35, 34, 33, 32, 31, 30, 28, + 27, 26, 25, 24, 23, 21, 20, 19, 11, 9, + 8, 7, 5, 3, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76 } ; /* Table of booleans, true if rule could match eol. */ @@ -553,11 +551,11 @@ char *yytext; MULT_TOK, DIV_TOK }; -#line 557 "lexer/lexer.c" +#line 555 "lexer/lexer.c" #define YY_NO_INPUT 1 -#line 38 "lexer/cppython.lex" +#line 36 "lexer/cppython.lex" /* regex and token definition */ -#line 561 "lexer/lexer.c" +#line 559 "lexer/lexer.c" #define INITIAL 0 @@ -772,12 +770,12 @@ YY_DECL } { -#line 61 "lexer/cppython.lex" +#line 57 "lexer/cppython.lex" /* reserved keywords */ -#line 781 "lexer/lexer.c" +#line 779 "lexer/lexer.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -804,13 +802,13 @@ YY_DECL while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 80 ) + if ( yy_current_state >= 77 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 131 ); + while ( yy_base[yy_current_state] != 125 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -846,101 +844,101 @@ YY_DECL case 1: YY_RULE_SETUP -#line 65 "lexer/cppython.lex" +#line 61 "lexer/cppython.lex" ; YY_BREAK /* arithmetic expressions */ case 2: YY_RULE_SETUP -#line 69 "lexer/cppython.lex" -{ handle_token(INTEGER_TOK); return INTEGER; }; +#line 65 "lexer/cppython.lex" +{ handle_token(FLOAT_TOK); return FLOAT; }; YY_BREAK case 3: YY_RULE_SETUP -#line 70 "lexer/cppython.lex" -; +#line 66 "lexer/cppython.lex" +{ handle_token(INTEGER_TOK); return INTEGER; }; YY_BREAK case 4: YY_RULE_SETUP -#line 71 "lexer/cppython.lex" +#line 67 "lexer/cppython.lex" { handle_token(SUB_TOK); return SUB; }; YY_BREAK case 5: YY_RULE_SETUP -#line 72 "lexer/cppython.lex" +#line 68 "lexer/cppython.lex" { handle_token(ADD_TOK); return ADD; }; YY_BREAK case 6: YY_RULE_SETUP -#line 73 "lexer/cppython.lex" +#line 69 "lexer/cppython.lex" { handle_token(MULT_TOK); return MULT; }; YY_BREAK case 7: YY_RULE_SETUP -#line 74 "lexer/cppython.lex" +#line 70 "lexer/cppython.lex" { handle_token(DIV_TOK); return DIV; }; YY_BREAK case 8: YY_RULE_SETUP -#line 75 "lexer/cppython.lex" +#line 71 "lexer/cppython.lex" { handle_token(ASSIGN_TOK); return ASSIGN; }; YY_BREAK case 9: YY_RULE_SETUP -#line 76 "lexer/cppython.lex" +#line 72 "lexer/cppython.lex" ; YY_BREAK /* conditional and booleans expressions */ case 10: YY_RULE_SETUP -#line 80 "lexer/cppython.lex" -; +#line 76 "lexer/cppython.lex" +{ handle_token(BOOLEAN_TOK); return BOOLEAN; }; YY_BREAK case 11: YY_RULE_SETUP -#line 81 "lexer/cppython.lex" +#line 77 "lexer/cppython.lex" ; YY_BREAK /* structure helpers */ case 12: /* rule 12 can match eol */ YY_RULE_SETUP -#line 85 "lexer/cppython.lex" +#line 81 "lexer/cppython.lex" ; YY_BREAK case 13: YY_RULE_SETUP -#line 86 "lexer/cppython.lex" +#line 82 "lexer/cppython.lex" ; YY_BREAK /* general */ case 14: /* rule 14 can match eol */ YY_RULE_SETUP -#line 90 "lexer/cppython.lex" +#line 86 "lexer/cppython.lex" { handle_token(NEWLINE_TOK); return NEWLINE; }; YY_BREAK case 15: YY_RULE_SETUP -#line 91 "lexer/cppython.lex" +#line 87 "lexer/cppython.lex" ; YY_BREAK case 16: YY_RULE_SETUP -#line 92 "lexer/cppython.lex" +#line 88 "lexer/cppython.lex" { handle_token(ID_TOK); return ID; }; YY_BREAK case 17: YY_RULE_SETUP -#line 93 "lexer/cppython.lex" +#line 89 "lexer/cppython.lex" { handle_token(ERROR_TOK); }; /* any character but newline */ YY_BREAK case 18: YY_RULE_SETUP -#line 95 "lexer/cppython.lex" +#line 91 "lexer/cppython.lex" ECHO; YY_BREAK -#line 944 "lexer/lexer.c" +#line 942 "lexer/lexer.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -1237,7 +1235,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 80 ) + if ( yy_current_state >= 77 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; @@ -1265,11 +1263,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 80 ) + if ( yy_current_state >= 77 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - yy_is_jam = (yy_current_state == 79); + yy_is_jam = (yy_current_state == 76); return yy_is_jam ? 0 : yy_current_state; } @@ -1916,7 +1914,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 95 "lexer/cppython.lex" +#line 91 "lexer/cppython.lex" /* @@ -1928,10 +1926,19 @@ void yyfree (void * ptr ) void handle_token(int token) { parser_column = lex_column; switch (token) { + case BOOLEAN_TOK: + if (LEX_VERBOSE) printf("Token: ", yytext); + if (strcmp(yytext, "True") == 0) yylval.int_value = 1; + else if (strcmp(yytext, "False") == 0) yylval.int_value = 0; + break; case INTEGER_TOK: if (LEX_VERBOSE) printf("Token: ", yytext); yylval.int_value = atoi(yytext); break; + case FLOAT_TOK: + if (LEX_VERBOSE) printf("Token: ", yytext); + yylval.float_value = atof(yytext); + break; case SUB_TOK: if (LEX_VERBOSE) printf("Token: ", yytext); yylval.op = yytext; diff --git a/src/lexer/lexer.h b/src/lexer/lexer.h index 6a2268b..6e05f7a 100644 --- a/src/lexer/lexer.h +++ b/src/lexer/lexer.h @@ -466,7 +466,7 @@ extern int yylex (void); #undef yyTABLES_NAME #endif -#line 95 "lexer/cppython.lex" +#line 91 "lexer/cppython.lex" #line 473 "lexer/lexer.h" diff --git a/src/parser/cppython.y b/src/parser/cppython.y index dc730ee..7ebd27e 100644 --- a/src/parser/cppython.y +++ b/src/parser/cppython.y @@ -16,21 +16,23 @@ %union { int int_value; + float float_value; char var[79]; char* op; ast_node* expression; } -%token ADD SUB MULT DIV ASSIGN -%token INTEGER -%token ID -%token NEWLINE +%token ADD SUB MULT DIV ASSIGN +%token INTEGER BOOLEAN +%token FLOAT +%token ID +%token NEWLINE -%left ASSIGN -%left ADD SUB -%left MULT DIV +%left ASSIGN +%left ADD SUB +%left MULT DIV -%type stmt simple_stmt var arith_expr term factor +%type stmt simple_stmt var expr arith_expr term factor %% @@ -38,7 +40,7 @@ input : /* empty */ { create_empy_ast(); } | input line { ; } ; -line : NEWLINE { create_empy_ast(); } +line : NEWLINE { ; } | stmt[U] NEWLINE { add_ast($U); } | error NEWLINE { yyerrok; } ; @@ -46,12 +48,16 @@ line : NEWLINE { create_empy_ast(); } stmt : simple_stmt[U] { $$ = print_exp($U); } ; -simple_stmt : var[L] ASSIGN arith_expr[R] { $$ = create_bin_expr("=", $L, $R); } +simple_stmt : var[L] ASSIGN expr[R] { $$ = create_bin_expr("=", $L, $R); } ; var : ID[U] { $$ = create_var_expr($U); } ; +expr : arith_expr[U] { $$ = print_exp($U); } + | BOOLEAN[U] { $$ = create_bool_expr($U); } + ; + arith_expr : arith_expr[L] ADD term[R] { $$ = create_bin_expr("+", $L, $R); } | arith_expr[L] SUB term[R] { $$ = create_bin_expr("-", $L, $R); } | term[U] { $$ = print_exp($U); } @@ -63,6 +69,7 @@ term : term[L] MULT factor[R] { $$ = create_bin_expr("*", $L, $R); ; factor : INTEGER[U] { $$ = create_int_expr($U); } + | FLOAT[U] { $$ = create_float_expr($U); } ; %% diff --git a/src/parser/parser.c b/src/parser/parser.c index b880e20..11dbf60 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -129,8 +129,10 @@ extern int yydebug; DIV = 261, ASSIGN = 262, INTEGER = 263, - ID = 264, - NEWLINE = 265 + BOOLEAN = 264, + FLOAT = 265, + ID = 266, + NEWLINE = 267 }; #endif @@ -141,11 +143,12 @@ union YYSTYPE #line 17 "parser/cppython.y" int int_value; + float float_value; char var[79]; char* op; ast_node* expression; -#line 149 "parser/parser.c" +#line 152 "parser/parser.c" }; typedef union YYSTYPE YYSTYPE; @@ -464,19 +467,19 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 2 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 16 +#define YYLAST 21 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 11 +#define YYNTOKENS 13 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 9 +#define YYNNTS 10 /* YYNRULES -- Number of rules. */ -#define YYNRULES 16 +#define YYNRULES 19 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 25 +#define YYNSTATES 28 #define YYUNDEFTOK 2 -#define YYMAXUTOK 265 +#define YYMAXUTOK 267 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM @@ -514,15 +517,15 @@ static const yytype_int8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10 + 5, 6, 7, 8, 9, 10, 11, 12 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int8 yyrline[] = { - 0, 37, 37, 38, 41, 42, 43, 46, 49, 52, - 55, 56, 57, 60, 61, 62, 65 + 0, 39, 39, 40, 43, 44, 45, 48, 51, 54, + 57, 58, 61, 62, 63, 66, 67, 68, 71, 72 }; #endif @@ -532,8 +535,9 @@ static const yytype_int8 yyrline[] = static const char *const yytname[] = { "$end", "error", "$undefined", "ADD", "SUB", "MULT", "DIV", "ASSIGN", - "INTEGER", "ID", "NEWLINE", "$accept", "input", "line", "stmt", - "simple_stmt", "var", "arith_expr", "term", "factor", YY_NULLPTR + "INTEGER", "BOOLEAN", "FLOAT", "ID", "NEWLINE", "$accept", "input", + "line", "stmt", "simple_stmt", "var", "expr", "arith_expr", "term", + "factor", YY_NULLPTR }; #endif @@ -543,11 +547,11 @@ static const char *const yytname[] = static const yytype_int16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265 + 265, 266, 267 }; # endif -#define YYPACT_NINF (-14) +#define YYPACT_NINF (-7) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) @@ -561,9 +565,9 @@ static const yytype_int16 yytoknum[] = STATE-NUM. */ static const yytype_int8 yypact[] = { - -14, 0, -14, -2, -14, -14, -14, 3, -14, 7, - -14, -14, 8, -14, -1, 1, -14, 8, 8, 8, - 8, 1, 1, -14, -14 + -7, 0, -7, -2, -7, -7, -7, 9, -7, -1, + -7, -7, -6, -7, -7, -7, -7, 5, 8, -7, + -3, -3, -3, -3, 8, 8, -7, -7 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -572,20 +576,20 @@ static const yytype_int8 yypact[] = static const yytype_int8 yydefact[] = { 2, 0, 1, 0, 9, 4, 3, 0, 7, 0, - 6, 5, 0, 16, 8, 12, 15, 0, 0, 0, - 0, 10, 11, 13, 14 + 6, 5, 0, 18, 11, 19, 8, 10, 14, 17, + 0, 0, 0, 0, 12, 13, 15, 16 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -14, -14, -14, -14, -14, -14, -14, -13, -8 + -7, -7, -7, -7, -7, -7, -7, -7, -5, -4 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 1, 6, 7, 8, 9, 14, 15, 16 + -1, 1, 6, 7, 8, 9, 16, 17, 18, 19 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -593,37 +597,39 @@ static const yytype_int8 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int8 yytable[] = { - 2, 3, 17, 18, 21, 22, 19, 20, 10, 4, - 5, 23, 24, 11, 12, 0, 13 + 2, 3, 13, 14, 15, 13, 12, 15, 20, 21, + 10, 4, 5, 22, 23, 24, 25, 0, 26, 27, + 0, 11 }; static const yytype_int8 yycheck[] = { - 0, 1, 3, 4, 17, 18, 5, 6, 10, 9, - 10, 19, 20, 10, 7, -1, 8 + 0, 1, 8, 9, 10, 8, 7, 10, 3, 4, + 12, 11, 12, 5, 6, 20, 21, -1, 22, 23, + -1, 12 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { - 0, 12, 0, 1, 9, 10, 13, 14, 15, 16, - 10, 10, 7, 8, 17, 18, 19, 3, 4, 5, - 6, 18, 18, 19, 19 + 0, 14, 0, 1, 11, 12, 15, 16, 17, 18, + 12, 12, 7, 8, 9, 10, 19, 20, 21, 22, + 3, 4, 5, 6, 21, 21, 22, 22 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_int8 yyr1[] = { - 0, 11, 12, 12, 13, 13, 13, 14, 15, 16, - 17, 17, 17, 18, 18, 18, 19 + 0, 13, 14, 14, 15, 15, 15, 16, 17, 18, + 19, 19, 20, 20, 20, 21, 21, 21, 22, 22 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_int8 yyr2[] = { 0, 2, 0, 2, 1, 2, 2, 1, 3, 1, - 3, 3, 1, 3, 3, 1, 1 + 1, 1, 3, 3, 1, 3, 3, 1, 1, 1 }; @@ -1319,97 +1325,115 @@ yyparse (void) switch (yyn) { case 2: -#line 37 "parser/cppython.y" +#line 39 "parser/cppython.y" { create_empy_ast(); } -#line 1325 "parser/parser.c" +#line 1331 "parser/parser.c" break; case 3: -#line 38 "parser/cppython.y" +#line 40 "parser/cppython.y" { ; } -#line 1331 "parser/parser.c" +#line 1337 "parser/parser.c" break; case 4: -#line 41 "parser/cppython.y" - { create_empy_ast(); } -#line 1337 "parser/parser.c" +#line 43 "parser/cppython.y" + { ; } +#line 1343 "parser/parser.c" break; case 5: -#line 42 "parser/cppython.y" +#line 44 "parser/cppython.y" { add_ast((yyvsp[-1].expression)); } -#line 1343 "parser/parser.c" +#line 1349 "parser/parser.c" break; case 6: -#line 43 "parser/cppython.y" +#line 45 "parser/cppython.y" { yyerrok; } -#line 1349 "parser/parser.c" +#line 1355 "parser/parser.c" break; case 7: -#line 46 "parser/cppython.y" +#line 48 "parser/cppython.y" { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1355 "parser/parser.c" +#line 1361 "parser/parser.c" break; case 8: -#line 49 "parser/cppython.y" +#line 51 "parser/cppython.y" { (yyval.expression) = create_bin_expr("=", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1361 "parser/parser.c" +#line 1367 "parser/parser.c" break; case 9: -#line 52 "parser/cppython.y" +#line 54 "parser/cppython.y" { (yyval.expression) = create_var_expr((yyvsp[0].var)); } -#line 1367 "parser/parser.c" +#line 1373 "parser/parser.c" break; case 10: -#line 55 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("+", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1373 "parser/parser.c" +#line 57 "parser/cppython.y" + { (yyval.expression) = print_exp((yyvsp[0].expression)); } +#line 1379 "parser/parser.c" break; case 11: -#line 56 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("-", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1379 "parser/parser.c" +#line 58 "parser/cppython.y" + { (yyval.expression) = create_bool_expr((yyvsp[0].int_value)); } +#line 1385 "parser/parser.c" break; case 12: -#line 57 "parser/cppython.y" - { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1385 "parser/parser.c" +#line 61 "parser/cppython.y" + { (yyval.expression) = create_bin_expr("+", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1391 "parser/parser.c" break; case 13: -#line 60 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("*", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1391 "parser/parser.c" +#line 62 "parser/cppython.y" + { (yyval.expression) = create_bin_expr("-", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1397 "parser/parser.c" break; case 14: -#line 61 "parser/cppython.y" - { (yyval.expression) = create_bin_expr("/", (yyvsp[-2].expression), (yyvsp[0].expression)); } -#line 1397 "parser/parser.c" +#line 63 "parser/cppython.y" + { (yyval.expression) = print_exp((yyvsp[0].expression)); } +#line 1403 "parser/parser.c" break; case 15: -#line 62 "parser/cppython.y" - { (yyval.expression) = print_exp((yyvsp[0].expression)); } -#line 1403 "parser/parser.c" +#line 66 "parser/cppython.y" + { (yyval.expression) = create_bin_expr("*", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1409 "parser/parser.c" break; case 16: -#line 65 "parser/cppython.y" +#line 67 "parser/cppython.y" + { (yyval.expression) = create_bin_expr("/", (yyvsp[-2].expression), (yyvsp[0].expression)); } +#line 1415 "parser/parser.c" + break; + + case 17: +#line 68 "parser/cppython.y" + { (yyval.expression) = print_exp((yyvsp[0].expression)); } +#line 1421 "parser/parser.c" + break; + + case 18: +#line 71 "parser/cppython.y" { (yyval.expression) = create_int_expr((yyvsp[0].int_value)); } -#line 1409 "parser/parser.c" +#line 1427 "parser/parser.c" + break; + + case 19: +#line 72 "parser/cppython.y" + { (yyval.expression) = create_float_expr((yyvsp[0].float_value)); } +#line 1433 "parser/parser.c" break; -#line 1413 "parser/parser.c" +#line 1437 "parser/parser.c" default: break; } @@ -1641,7 +1665,7 @@ yyparse (void) #endif return yyresult; } -#line 68 "parser/cppython.y" +#line 75 "parser/cppython.y" void yyerror(const char *s) { diff --git a/src/parser/parser.h b/src/parser/parser.h index a9ac464..1c88291 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -55,8 +55,10 @@ extern int yydebug; DIV = 261, ASSIGN = 262, INTEGER = 263, - ID = 264, - NEWLINE = 265 + BOOLEAN = 264, + FLOAT = 265, + ID = 266, + NEWLINE = 267 }; #endif @@ -67,11 +69,12 @@ union YYSTYPE #line 17 "parser/cppython.y" int int_value; + float float_value; char var[79]; char* op; ast_node* expression; -#line 75 "parser/parser.h" +#line 78 "parser/parser.h" }; typedef union YYSTYPE YYSTYPE; diff --git a/src/parser/parser.output b/src/parser/parser.output index 1ac5eac..183eb06 100644 --- a/src/parser/parser.output +++ b/src/parser/parser.output @@ -11,63 +11,72 @@ Grammar 6 stmt: simple_stmt - 7 simple_stmt: var ASSIGN arith_expr + 7 simple_stmt: var ASSIGN expr 8 var: ID - 9 arith_expr: arith_expr ADD term - 10 | arith_expr SUB term - 11 | term + 9 expr: arith_expr + 10 | BOOLEAN - 12 term: term MULT factor - 13 | term DIV factor - 14 | factor + 11 arith_expr: arith_expr ADD term + 12 | arith_expr SUB term + 13 | term - 15 factor: INTEGER + 14 term: term MULT factor + 15 | term DIV factor + 16 | factor + + 17 factor: INTEGER + 18 | FLOAT Terminals, with rules where they appear $end (0) 0 error (256) 5 - ADD (258) 9 - SUB (259) 10 - MULT (260) 12 - DIV (261) 13 + ADD (258) 11 + SUB (259) 12 + MULT (260) 14 + DIV (261) 15 ASSIGN (262) 7 - INTEGER (263) 15 - ID (264) 8 - NEWLINE (265) 3 4 5 + INTEGER (263) 17 + BOOLEAN (264) 10 + FLOAT (265) 18 + ID (266) 8 + NEWLINE (267) 3 4 5 Nonterminals, with rules where they appear - $accept (11) + $accept (13) on left: 0 - input (12) + input (14) on left: 1 2 on right: 0 2 - line (13) + line (15) on left: 3 4 5 on right: 2 - stmt (14) + stmt (16) on left: 6 on right: 4 - simple_stmt (15) + simple_stmt (17) on left: 7 on right: 6 - var (16) + var (18) on left: 8 on right: 7 - arith_expr (17) - on left: 9 10 11 - on right: 7 9 10 - term (18) - on left: 12 13 14 - on right: 9 10 11 12 13 - factor (19) - on left: 15 - on right: 12 13 14 + expr (19) + on left: 9 10 + on right: 7 + arith_expr (20) + on left: 11 12 13 + on right: 9 11 12 + term (21) + on left: 14 15 16 + on right: 11 12 13 14 15 + factor (22) + on left: 17 18 + on right: 14 15 16 State 0 @@ -146,7 +155,7 @@ State 8 State 9 - 7 simple_stmt: var . ASSIGN arith_expr + 7 simple_stmt: var . ASSIGN expr ASSIGN shift, and go to state 12 @@ -167,124 +176,152 @@ State 11 State 12 - 7 simple_stmt: var ASSIGN . arith_expr + 7 simple_stmt: var ASSIGN . expr INTEGER shift, and go to state 13 + BOOLEAN shift, and go to state 14 + FLOAT shift, and go to state 15 - arith_expr go to state 14 - term go to state 15 - factor go to state 16 + expr go to state 16 + arith_expr go to state 17 + term go to state 18 + factor go to state 19 State 13 - 15 factor: INTEGER . + 17 factor: INTEGER . - $default reduce using rule 15 (factor) + $default reduce using rule 17 (factor) State 14 - 7 simple_stmt: var ASSIGN arith_expr . - 9 arith_expr: arith_expr . ADD term - 10 | arith_expr . SUB term + 10 expr: BOOLEAN . - ADD shift, and go to state 17 - SUB shift, and go to state 18 - - $default reduce using rule 7 (simple_stmt) + $default reduce using rule 10 (expr) State 15 - 11 arith_expr: term . - 12 term: term . MULT factor - 13 | term . DIV factor + 18 factor: FLOAT . - MULT shift, and go to state 19 - DIV shift, and go to state 20 - - $default reduce using rule 11 (arith_expr) + $default reduce using rule 18 (factor) State 16 - 14 term: factor . + 7 simple_stmt: var ASSIGN expr . - $default reduce using rule 14 (term) + $default reduce using rule 7 (simple_stmt) State 17 - 9 arith_expr: arith_expr ADD . term + 9 expr: arith_expr . + 11 arith_expr: arith_expr . ADD term + 12 | arith_expr . SUB term - INTEGER shift, and go to state 13 + ADD shift, and go to state 20 + SUB shift, and go to state 21 - term go to state 21 - factor go to state 16 + $default reduce using rule 9 (expr) State 18 - 10 arith_expr: arith_expr SUB . term + 13 arith_expr: term . + 14 term: term . MULT factor + 15 | term . DIV factor - INTEGER shift, and go to state 13 + MULT shift, and go to state 22 + DIV shift, and go to state 23 - term go to state 22 - factor go to state 16 + $default reduce using rule 13 (arith_expr) State 19 - 12 term: term MULT . factor - - INTEGER shift, and go to state 13 + 16 term: factor . - factor go to state 23 + $default reduce using rule 16 (term) State 20 - 13 term: term DIV . factor + 11 arith_expr: arith_expr ADD . term INTEGER shift, and go to state 13 + FLOAT shift, and go to state 15 - factor go to state 24 + term go to state 24 + factor go to state 19 State 21 - 9 arith_expr: arith_expr ADD term . - 12 term: term . MULT factor - 13 | term . DIV factor + 12 arith_expr: arith_expr SUB . term - MULT shift, and go to state 19 - DIV shift, and go to state 20 + INTEGER shift, and go to state 13 + FLOAT shift, and go to state 15 - $default reduce using rule 9 (arith_expr) + term go to state 25 + factor go to state 19 State 22 - 10 arith_expr: arith_expr SUB term . - 12 term: term . MULT factor - 13 | term . DIV factor + 14 term: term MULT . factor - MULT shift, and go to state 19 - DIV shift, and go to state 20 + INTEGER shift, and go to state 13 + FLOAT shift, and go to state 15 - $default reduce using rule 10 (arith_expr) + factor go to state 26 State 23 - 12 term: term MULT factor . + 15 term: term DIV . factor + + INTEGER shift, and go to state 13 + FLOAT shift, and go to state 15 - $default reduce using rule 12 (term) + factor go to state 27 State 24 - 13 term: term DIV factor . + 11 arith_expr: arith_expr ADD term . + 14 term: term . MULT factor + 15 | term . DIV factor + + MULT shift, and go to state 22 + DIV shift, and go to state 23 + + $default reduce using rule 11 (arith_expr) + + +State 25 + + 12 arith_expr: arith_expr SUB term . + 14 term: term . MULT factor + 15 | term . DIV factor + + MULT shift, and go to state 22 + DIV shift, and go to state 23 + + $default reduce using rule 12 (arith_expr) + + +State 26 + + 14 term: term MULT factor . + + $default reduce using rule 14 (term) + + +State 27 + + 15 term: term DIV factor . - $default reduce using rule 13 (term) + $default reduce using rule 15 (term) diff --git a/src/tests/parser/invalid_1.ppy b/src/tests/parser/invalid_1.ppy index 724a241..4542339 100644 --- a/src/tests/parser/invalid_1.ppy +++ b/src/tests/parser/invalid_1.ppy @@ -1,2 +1,6 @@ -1 + [ -@ +x = 5 + 2.3 - 1 / 9 +z = 4.6 + 4 * 2 * 53.3 - 3 / 0.00 +w = 9.0 +$ +5.6 +p = 1 - \ No newline at end of file diff --git a/src/tests/parser/valid_2.ppy b/src/tests/parser/valid_2.ppy index 30ec71b..9054075 100644 --- a/src/tests/parser/valid_2.ppy +++ b/src/tests/parser/valid_2.ppy @@ -1 +1,6 @@ -5 - 1 +x = 5 + 2.3 - 1 / 9 +z = 4.6 + 4 * 2 * 53.3 - 3 / 0.00 +w = 9.0 +t = True +o = 2 +p = False