78 lines
1.7 KiB
Plaintext
78 lines
1.7 KiB
Plaintext
%{
|
|
|
|
#include <cstdio>
|
|
#include <string>
|
|
|
|
#include "syntax.h"
|
|
|
|
using namespace std;
|
|
|
|
int yylex();
|
|
void yyerror(const char* p) { fprintf(stderr, p); }
|
|
|
|
%}
|
|
|
|
%define parse.trace
|
|
|
|
%union {
|
|
float num;
|
|
std::string *sym;
|
|
Node *expr;
|
|
NodeList *exprlist;
|
|
}
|
|
|
|
%token <sym> ID
|
|
%token <num> NUM
|
|
%token <sym> STRING
|
|
|
|
%token STOP
|
|
%token INDENT DEDENT
|
|
%token IF ELIF ELSE
|
|
|
|
%right GETS
|
|
%left CAT
|
|
%left '+' '-'
|
|
%left '/' '*'
|
|
%left MAPS
|
|
|
|
%nterm <expr> expr
|
|
%nterm <exprlist> exprlist
|
|
|
|
%%
|
|
program: statements | statements statement;
|
|
statements: statements statement STOP
|
|
| statements STOP
|
|
| // null production ;
|
|
statement: assignment | funcall | conditional;
|
|
assignment: ID GETS expr;
|
|
assignments: assignments assignment STOP | // null production;
|
|
expr: funcdef
|
|
| funcall
|
|
| objdef
|
|
| expr CAT expr { $$ = new OpNode(CAT, $1, $3); }
|
|
| expr '+' expr { $$ = new OpNode('+', $1, $3); }
|
|
| expr '-' expr { $$ = new OpNode('-', $1, $3); }
|
|
| expr '*' expr { $$ = new OpNode('*', $1, $3); }
|
|
| expr '/' expr { $$ = new OpNode('/', $1, $3); }
|
|
| '(' expr ')' {$$ = $2;}
|
|
| ID {$$ = new IdNode($1);}
|
|
| NUM {$$ = new NumNode($1);}
|
|
| STRING {$$ = new StringNode($1);};
|
|
|
|
funcdef: param MAPS expr | param MAPS block;
|
|
param: ID | '_' | // null production;
|
|
|
|
funcall: ID '(' exprlist ')' { print_expression_list($3); }
|
|
exprlist: exprlist ',' expr { $1 -> push_back($3); $$ = $1; }
|
|
| expr { $$ = new NodeList(); $$ -> push_back($1); }
|
|
| { $$ = new NodeList(); } // null production;
|
|
|
|
conditional: IF expr block elifs
|
|
| IF expr block elifs ELSE block;
|
|
elifs: ELIF expr block elifs| // null production;
|
|
|
|
objdef: '{' block_assignments '}' | '{' '}'
|
|
|
|
block: STOP INDENT statement statements DEDENT
|
|
block_assignments: STOP INDENT assignments DEDENT
|
|
%% |