deelang/src/parser.y
2021-12-08 14:58:36 -06:00

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
%%