Skip to content
Permalink
master
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time
%{
#include "interpreter.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <forward_list>
using namespace Interpreter;
extern int yylex();
extern int yyparse();
extern FILE* yyin;
extern int yylineno;
void yyerror(const char* s);
int yydebug=1;
Interpreter::Statements* root;
%}
%code requires
{
#include "interpreter.h"
#include <forward_list>
}
%union {
char* name;
char* op;
int val;
Interpreter::Id* id_node;
Interpreter::Val* val_node;
Interpreter::Statements* statements_node;
Interpreter::Statement* statement_node;
Interpreter::Expression* expression_node;
std::forward_list<Interpreter::ProcedureCallArgument*>* funccallargument_node;
std::forward_list<Interpreter::Id*>* funcdefargument_node;
}
%token<val> T_INT
%token<name> T_ID
%token<op> T_PLUS T_MINUS T_MULTIPLY T_DIVIDE
%token<op> T_RELOP
%token T_DEF
%token T_NEWLINE
%left '+' '-'
%left '*' '/'
%nonassoc '<' '>' T_LE T_GE T_EQ T_NE
%type<id_node> id
%type<expression_node> number
%type<statements_node> stmts
%type<statement_node> stmt print assn cond funcdef funccall
%type<expression_node> expr factor
%type<funcdefargument_node> defargs optdefargs
%type<funccallargument_node> callargs optcallargs
%start program
%%
program : stmts { root = $1; $1->Execute(); }
stmts : stmt T_NEWLINE stmts { $$ = new Statements($1,$3); }
| stmt { $$ = new Statements($1,nullptr); }
| T_NEWLINE stmts { $$ = $2; }
| /* e */ { $$ = nullptr; }
;
stmt : assn
| cond
| print
| funcdef
| funccall
;
print : '&' expr { $$ = new Print($2); }
;
assn : '{' expr '}' '|' ':' id { $$ = new Assignment($6,$2); }
;
cond : '(' expr ')' '?' '?' '(' stmts ')' { $$ = new Conditional($2,$7); }
;
expr : expr '<' expr { $$ = new ExpressionNode($1,$3, new Op("<")); }
| expr '>' expr { $$ = new ExpressionNode($1,$3, new Op(">")); }
| expr T_EQ expr { $$ = new ExpressionNode($1,$3, new Op("==")); }
| expr T_NE expr { $$ = new ExpressionNode($1,$3, new Op("!=")); }
| expr T_LE expr { $$ = new ExpressionNode($1,$3, new Op("<=")); }
| expr T_GE expr { $$ = new ExpressionNode($1,$3, new Op(">=")); }
| expr '+' expr { $$ = new ExpressionNode($1,$3, new Op("+")); }
| expr '-' expr { $$ = new ExpressionNode($1,$3, new Op("-")); }
| expr '*' expr { $$ = new ExpressionNode($1,$3, new Op("*")); }
| expr '/' expr { $$ = new ExpressionNode($1,$3, new Op("/")); }
| factor
;
factor : '(' expr ')' { $$ = $2; }
| number { $$ = $1; }
| id { $$ = $1; }
;
funcdef : T_DEF id '(' optdefargs ')' '=' '{' stmts '}' { $$ = new ProcedureDeclaration($2,$4,$8); }
;
funccall : id '(' optcallargs ')' { $$ = new ProcedureCall($1,$3); }
;
optdefargs : defargs
| { $$ = new std::forward_list<Id*>(); }
;
optcallargs : callargs
| { $$ = new std::forward_list<ProcedureCallArgument*>(); }
;
defargs : id { $$ = new std::forward_list<Id*>(); $$->push_front($1); }
| id ',' defargs { $$->push_front($1); }
;
callargs : expr { $$ = new std::forward_list<ProcedureCallArgument*>(); $$->push_front(new ProcedureCallArgument($1)); }
| expr ',' callargs { $$->push_front(new ProcedureCallArgument($1)); }
;
id : T_ID { $$ = new Id(strdup($1)); }
number : T_INT { $$ = new Val($1); }
%%
extern int yy_flex_debug;
int main() {
yy_flex_debug = 0;
yyparse();
return 0;
}
void yyerror(const char* s) {
fprintf(stderr, "syntax error: %s: line %d\n", s, yylineno);
exit(1);
}