6A.l
%{ #include "6A.tab.h" void yyerror(const char *); int position = 0; %} %% [0-9]+ { position += yyleng; yylval.ival = atoi(yytext); return INTEGER; } "^T" { position += yyleng; return TRANSPOSE; } "+"|"-"|"*" { position += yyleng; yylval.ival = position; return yytext[0]; } "("|")"|"["|"]"|"," { position += yyleng; return yytext[0]; } [ \t]+ { position += yyleng; } \n { return yytext[0]; } . { yyerror("invalid input"); } %% |
6A.y
%{ #include <stdio.h> void yyerror(const char *); int yylex(void); void semantic_err(const int); %} %code requires { typedef struct { int row; int col; } matrix_dim; } %union { int ival; matrix_dim md; } /* declarations */ %token <ival> INTEGER %type <md> expr %type <md> matrix /* precedences */ %left <ival> '+' '-' %left <ival> '*' %right TRANSPOSE %% line : expr '\n' {printf("Accepted\n");} ; expr : expr '+' expr { if ($1.row == $3.row && $1.col == $3.col) { $$ = $1; } else { semantic_err($2); return 0; } } | expr '-' expr { if ($1.row == $3.row && $1.col == $3.col) { $$ = $1; } else { semantic_err($2); return 0; } } | expr '*' expr { if ($1.col == $3.row) { $$.row = $1.row; $$.col = $3.col; } else { semantic_err($2); return 0; } } | '(' expr ')' {$$ = $2;} | expr TRANSPOSE { $$.row = $1.col; $$.col = $1.row; } | matrix ; matrix : '[' INTEGER ',' INTEGER ']' { $$.row = $2; $$.col = $4; } ; %% void semantic_err(const int col_num) { printf("Semantic error on col %d\n", col_num); } void yyerror(const char *message) { fprintf(stderr, "%s\n", message); } int main(void) { yyparse(); return 0; } |
6B.l
%{ #include "BA3B.tab.h" void yyerror(const char *); %} %% [0-9]+ { yylval.ival = atoi(yytext); return INTEGER; } \n { return yytext[0]; } "add" { return ADD; } "sub" { return SUB; } "mul" { return MUL; } "mod" { return MOD; } "inc" { return INC; } "dec" { return DEC; } "load" { return LOAD; } [ \t]+ { ; } . { yyerror("invalid input"); } %% |
6B.y
%{ #include <iostream> #include <stack> int yylex(void); void yyerror(const char *); std::stack<int> s; %} /* This section defines the additional function using the data type in * `%code requires` section. */ %code provides {} %union{ int ival; } /* declarations */ %token <ival> INTEGER %token ADD %token SUB %token MUL %token MOD %token INC %token DEC %token LOAD %type <ival> expr %% program : lines { if (s.size() != 1) { std::cout << "Invalid format" << std::endl; exit(0); } else std::cout << s.top() << std::endl; } lines : lines line {;} | line {;} ; line : expr '\n' {;} | expr {;} | '\n' {;} ; expr : LOAD INTEGER {s.push($2);} | ADD { if (s.size() < 2) { std::cout << "Invalid format" << std::endl; exit(0); } else { int a = s.top(); s.pop(); int b = s.top(); s.pop(); s.push(a + b); } } | SUB { if (s.size() < 2) { std::cout << "Invalid format" << std::endl; exit(0); } else { int a = s.top(); s.pop(); int b = s.top(); s.pop(); s.push(a - b); } } | MUL { if (s.size() < 2) { std::cout << "Invalid format" << std::endl; exit(0); } else { int a = s.top(); s.pop(); int b = s.top(); s.pop(); s.push(a * b); } } | MOD { if (s.size() < 2) { std::cout << "Invalid format" << std::endl; exit(0); } else { int a = s.top(); s.pop(); int b = s.top(); s.pop(); s.push(a % b); } } | INC { if (s.size() < 1) { std::cout << "Invalid format" << std::endl; exit(0); } else { int a = s.top(); s.pop(); s.push(++a); } } | DEC { if (s.size() < 1) { std::cout << "Invalid format" << std::endl; exit(0); } else { int a = s.top(); s.pop(); s.push(--a); } } ; %% void yyerror(const char *message) { std::cout << "Invalid format" << std::endl; } int main(void) { yyparse(); return 0; } |