diff --git a/lab-5/main.c b/lab-5/main.c index e464500..1a4d24d 100644 --- a/lab-5/main.c +++ b/lab-5/main.c @@ -4,10 +4,15 @@ Simply invoke the parser generated by bison, and then display the output. */ #include "expr.h" +#include "token.h" #include /* Clunky: Declare the parse function generated from parser.bison */ -extern int yyparse(struct stmt *parser_result); +// extern int yyparse(struct stmt *parser_result); +extern int yyparse(); +extern char *yytext; + +extern int yylex(); /* Clunky: Declare the result of the parser from parser.bison */ @@ -17,8 +22,9 @@ int main(int argc, char *argv[]) { printf("Lab 6 Example Interpreter Compiler\n"); printf( "Enter an infix expression using the operators +-*/() ending with ;\n\n"); + - if (yyparse(parser_result) == 0) { + if (yyparse() == 0) { printf("Parse successful: "); if (parser_result != NULL) { stmt_print(parser_result); @@ -27,7 +33,6 @@ int main(int argc, char *argv[]) { stmt_evaluate(parser_result); printf("\n"); } - printf("parser_result is %p\n", parser_result); return 0; } else { printf("Parse failed!\n"); diff --git a/lab-5/parser.bison b/lab-5/parser.bison index 4e91288..480271d 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -19,13 +19,16 @@ Clunky: Manually declare the interface to the scanner generated by flex. extern char *yytext; extern int yylex(); -void yyerror(struct stmt *parser_result, const char*); - +// void yyerror(struct stmt *parser_result, const char*); +void yyerror(const char*); extern int yylineno; + +struct stmt *parser_result = 0; + %} -%parse-param {struct stmt *parser_result} +// %parse-param {struct stmt *parser_result} %debug %define parse.error detailed @@ -84,19 +87,21 @@ extern int yylineno; %% -file : statements -statements : statement_list +file : statement_list + {parser_result = $1; return 0;} ; statement_list : statement_list statement + { $$ = $1; $1->next = $2; } | statement + { $$ = $1; } ; statement : section | sect_data | simple_stmt + {$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL);} | data_space | data_declaration ; - section : type TOKEN_KEYWORD_DIVISION TOKEN_DOT | type TOKEN_RUN TOKEN_DOT ; @@ -108,12 +113,14 @@ type : TOKEN_KEYWORD_IDENTIFICATION | TOKEN_KEYWORD_DATA ; simple_stmt : cbl_func_stmt - | if_branch + {$$ = $1;} + | if_branch | else_parts | perform_stmt ; cbl_func_stmt : cbl_function - | cbl_function op_parms + | cbl_function op_parms + {$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, NULL, NULL, NULL);} | cbl_function assignment_stmt | cbl_function op_parm assignment_stmt ; @@ -121,12 +128,17 @@ assignment_stmt : TOKEN_EQUAL op_parms | TOKEN_KEYWORD_TO op_parms ; op_parms : op_parm - | op_parms op_parm + {$$ = $1;} + | op_parm op_parms + {$$ = $1; $1->next_expr = $2;} ; op_parm : mathmaticalexpr + {$$ = $1;} | booleanexpr + {$$ = $1;} ; -term : mathmaticalexpr +term : mathmaticalexpr + {$$ = $1;} ; math_op : TOKEN_ADD | TOKEN_SUB @@ -135,9 +147,12 @@ math_op : TOKEN_ADD | TOKEN_EXPONENTIAL ; mathmaticalexpr : type_expr + {$$ = $1;} | mathmaticalexpr math_op term | container_expr + {$$ = $1;} | type_expr container_expr + {$$ = $1; $1->next_expr = $2;} ; container_expr : TOKEN_LEFT_PARENTHESIS mathmaticalexpr TOKEN_RIGHT_PARENTHESIS ; @@ -146,15 +161,21 @@ booleanexpr : mathmaticalexpr TOKEN_LESS_THAN term | mathmaticalexpr TOKEN_EQUAL term ; type_expr : TOKEN_IDENT + {$$ = expr_create_name(yytext);} | TOKEN_INTEGER + {$$ = expr_create_integer_literal(yytext);} | TOKEN_STRING + {$$ = expr_create_string_literal(atoi(yytext));} | TOKEN_SPACE + {$$ = expr_create_integer_literal(0);} | TOKEN_SUB TOKEN_IDENT + {$$ = expr_create_integer_literal(atoi(yytext) * -1);} | ext_function ; ext_function : TOKEN_KEYWORD_FUNCTION TOKEN_IDENT TOKEN_LEFT_PARENTHESIS TOKEN_IDENT TOKEN_RIGHT_PARENTHESIS ; cbl_function : TOKEN_DISPLAY + {$$ = stmt_create(STMT_PRINT, NULL, NULL, NULL, NULL, NULL, NULL, NULL);} | TOKEN_MOVE | TOKEN_KEYWORD_COMPUTE ; @@ -204,6 +225,10 @@ data_declaration: simple_decl | complex_decl ; %% -void yyerror(struct stmt *parser_result, const char* msg) { +// void yyerror(struct stmt *parser_result, const char* msg) { +// fprintf(stderr, "Error | Line: %d\n%s\n",yylineno,msg); +// } + +void yyerror(const char* msg) { fprintf(stderr, "Error | Line: %d\n%s\n",yylineno,msg); -} +} \ No newline at end of file diff --git a/lab-5/parser.bison.new b/lab-5/parser.bison.new new file mode 100644 index 0000000..50bf300 --- /dev/null +++ b/lab-5/parser.bison.new @@ -0,0 +1,117 @@ +%{ +#define YYDEBUG 1 +#include +#include +#include +#include +#include "expr.h" + +/* +YYSTYPE is the lexical value returned by each rule in a bison grammar. +By default, it is an integer. In this example, we are returning a pointer to an expression. +*/ + +#define YYSTYPE struct stmt * + +/* +Clunky: Manually declare the interface to the scanner generated by flex. +*/ + +extern char *yytext; +extern int yylex(); +// void yyerror(struct stmt *parser_result, const char*); +void yyerror(const char*); + +extern int yylineno; + +struct stmt *parser_result = 0; + +%} + +// %parse-param {struct stmt *parser_result} + +%debug +%define parse.error detailed + +%token TOKEN_EOF +%token TOKEN_KEYWORD_IDENTIFICATION +%token TOKEN_KEYWORD_DIVISION +%token TOKEN_KEYWORD_DATA +%token TOKEN_KEYWORD_SECTION +%token TOKEN_PROGRAM_ID +%token TOKEN_WORKING_STORAGE +%token TOKEN_PROCEDURE +%token TOKEN_STOP +%token TOKEN_RUN +%token TOKEN_MOVE +%token TOKEN_KEYWORD_TO +%token TOKEN_PERFORM +%token TOKEN_VARYING +%token TOKEN_KEYWORD_FROM +%token TOKEN_KEYWORD_BY +%token TOKEN_UNTIL +%token TOKEN_END_PERFORM +%token TOKEN_IF +%token TOKEN_ELSE_IF +%token TOKEN_ELSE +%token TOKEN_END_IF +%token TOKEN_SPACE +%token TOKEN_KEYWORD_OCCURS +%token TOKEN_KEYWORD_VALUE +%token TOKEN_KEYWORD_COMPUTE +%token TOKEN_KEYWORD_FUNCTION +%token TOKEN_IDENT +%token TOKEN_STRING +%token TOKEN_INTEGER +%token TOKEN_PICTURE +%token TOKEN_ALPHANUMERIC +%token TOKEN_NUMERIC +%token TOKEN_SIGNED_NUMERIC +%token TOKEN_IMPLIED_DECIMAL +%token TOKEN_COMPUTATION_LEVEL_0 +%token TOKEN_COMPUTATION_LEVEL_1 +%token TOKEN_COMPUTATION_LEVEL_2 +%token TOKEN_COMPUTATION_LEVEL_3 +%token TOKEN_LEFT_PARENTHESIS +%token TOKEN_RIGHT_PARENTHESIS +%token TOKEN_DOT +%token TOKEN_ADD +%token TOKEN_SUB +%token TOKEN_MULTIPLY +%token TOKEN_DIVIDE +%token TOKEN_EQUAL +%token TOKEN_GREATER_THAN +%token TOKEN_LESS_THAN +%token TOKEN_EXPONENTIAL +%token TOKEN_DISPLAY + + +%% +file : statements + {parser_result = $1; return 0;} + ; +statements : statements statement + { $$ = $1; $1->next = $2; } + | statement + { $$ = $1; } + ; +statement : simple_stmt + {$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL);} + ; +simple_stmt : cbl_func_stmt + {$$ = $1;} + ; +cbl_func_stmt : display_stmt + {$$ = $1;} + ; +display_stmt : TOKEN_DISPLAY expr + {$$ = stmt_create(STMT_PRINT, NULL, NULL, $2, NULL, NULL, NULL, NULL);} + ; +expr : TOKEN_STRING + { $$ = expr_create_string_literal(yytext);} + ; +%% + +void yyerror(const char* msg) { + fprintf(stderr, "Error | Line: %d\n%s\n",yylineno,msg); +} \ No newline at end of file