Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ////////////////////////////////////////////////////////////////////////////////
- // THE SCOTCH-WARE LICENSE (Revision 0):
- // <aaronryool@gmail.com> wrote this file. As long as you retain this notice you
- // can do whatever you want with this stuff. If we meet some day, and you think
- // this stuff is worth it, you can buy me a shot of scotch in return
- ////////////////////////////////////////////////////////////////////////////////
- %require "3.2"
- %language "c++"
- %define api.namespace {yy}
- %define api.parser.class {parser}
- %define api.value.type variant
- %define api.token.constructor
- %defines
- %output "src/parser.yacc.cc"
- %parse-param { yy::Lexer &lexer } // Construct parser object with lexer
- %{
- #include <parser.lex.h>
- #undef yylex
- #define yylex lexer.yylex // Within bison's parse() we should invoke lexer.yylex(), not the global yylex()
- %}
- %code requires{
- #include <ast/ast.h>
- namespace yy {
- class Lexer; // Generated by reflex with namespace=yy lexer=Lexer lex=yylex
- }
- }
- %define api.token.prefix {TOK_}
- %token LAND
- %token LOR
- %token LEQ
- %token LNEQ
- %token LTEQ
- %token GTEQ
- %token POW
- %token RETURNS
- %token EXIT
- %token PRINT
- %token IF
- %token ELSE
- %token WHILE
- %token FOR
- %token TRUE
- %token FALSE
- %token IMPORT
- %token IRUN
- %token ISTART
- %token IROOT
- %token TYPE_INT
- %token TYPE_FLOAT
- %token TYPE_STRING
- %token TYPE_NONE
- %token TYPE_TRUTH
- %token TYPE_LIST
- %token TYPE
- %token <int> INT
- %token <double> FLOAT
- %token <std::string> STRING
- %token <std::string> VAR
- %type <RootNode*> block
- %type <AstNode*> statement
- %type <AstNode*> expression
- %type <ListNode*> list_expression
- %type <std::vector<AstNode*>> expression_list
- %type <Type> type_statement
- %type <bool> TRUTH
- %type <FunctionCallNode*> function_expression
- %type <FunctionNode*> function_statement
- %type <std::list<std::tuple<std::string, Type>>> input_list
- %type <IfNode*> if_statement
- %type <AstNode*> loop_statement
- //%type <AstNode*> interactive
- %left ','
- %right '='
- %left LAND LOR
- %left LEQ LNEQ LTEQ GTEQ '<' '>'
- %left '&' '|' '^'
- %left '+' '-'
- %left '*' '/' '%'
- %left POW
- %right '(' ')'
- %right ADDEQ
- %right SUBEQ
- %right POWEQ
- %right MULEQ
- %right DIVEQ
- %right MODEQ
- %right BANDEQ
- %right BOREQ
- %right BXOREQ
- %left ADDADD
- %left SUBSUB
- %precedence NEG // negation
- %precedence NOT '!'
- %precedence TYPE
- %right ISTART
- %left IRUN
- %precedence IF
- %precedence ':'
- %right ';'
- %nonassoc NO_ELSE
- %nonassoc ELSE
- %%
- // root of AST, things actually get to run here
- run:
- block { if($1) $1->walk(); }
- ;
- // things attach to a block node, which is the root
- block: { $$ = new RootNode; }
- /*
- | IROOT { $$ = new RootNode; current_scope = static_cast<RootNode*>($$); }
- | block interactive {
- if ($2 != NULL) {
- $$ = current_scope->attach_statement($2);
- // check state position, then act accoringly
- $$ = static_cast<RootNode*>(current_scope->state_start->walk());
- }
- }
- */
- | block statement ';' {
- if ($2 != NULL) // cathces special case of empty statements not filtered by lex
- $$ = $1->attach_statement($2);
- else $$ = $1;
- }
- | block if_statement { $$ = $1->attach_statement($2); }
- | block loop_statement { $$ = $1->attach_statement($2); }
- | block function_statement { $$ = $1->attach_statement($2); }
- ;
- /*
- interactive:
- ISTART statement IRUN { $$ = $2; }
- | ISTART statement ';' IRUN { $$ = $2; }
- | ISTART if_statement IRUN { $$ = $2; }
- | ISTART loop_statement IRUN { $$ = $2; }
- | ISTART function_statement IRUN { $$ = $2; }
- ;
- */
- type_statement:
- TYPE_NONE {$$ = NONE;}
- | TYPE_INT {$$ = INT;}
- | TYPE_FLOAT {$$ = FLOAT;}
- | TYPE_STRING {$$ = STRING;}
- | TYPE_TRUTH {$$ = TRUTH;}
- | TYPE_LIST {$$ = LIST;}
- ;
- // statements are branches of expressions
- statement:
- expression { $$ = $1; }
- | PRINT expression { $$ = new BuiltinNode(PRINT, $2); }
- | EXIT expression { $$ = new BuiltinNode(EXIT, $2); }
- | RETURNS expression { $$ = new FunctionReturnNode($2); }
- ;
- TRUTH:
- FALSE { $$ = 0; }
- | TRUE { $$ = 1; }
- ;
- expression_list:
- expression ',' expression { $$.push_back($1); $$.push_back($3);}
- | expression_list ',' expression { $$.insert($$.begin(), $1.begin(), $1.end()); $$.push_back($3); }
- ;
- list_expression:
- '[' expression_list ']' { $$ = new ListNode($2); }
- | '[' expression ']' {
- $$ = new ListNode(std::vector<AstNode*>({$2}));
- }
- ;
- expression: {;} // ignore empty expressions
- | INT { $$ = new IntNode($1); }
- | TRUTH { $$ = new TruthNode($1); }
- | FLOAT { $$ = new FloatNode($1); }
- | STRING { $$ = new StringNode($1); }
- | TYPE_NONE { $$ = new NoneNode(); }
- | VAR '=' expression { $$ = new AssignmentNode($1, $3); }
- | VAR { $$ = new SymbolReference($1); }
- | list_expression { $$ = $1; }
- | TYPE expression { $$ = new BuiltinNode(TYPE, $2); }
- | NOT expression %prec NEG { $$ = new MathNode(BNOT, NULL, $2); }
- | '(' expression ')' { $$ = $2; }
- | expression '+' expression { $$ = new MathNode(ADD, $1, $3); }
- | expression '-' expression { $$ = new MathNode(SUB, $1, $3); }
- | expression '*' expression { $$ = new MathNode(MUL, $1, $3); }
- | expression '/' expression { $$ = new MathNode(DIV, $1, $3); }
- | expression '%' expression { $$ = new MathNode(MOD, $1, $3); }
- | expression POW expression { $$ = new MathNode(POW, $1, $3); }
- | expression '&' expression { $$ = new MathNode(BAND, $1, $3); }
- | expression '|' expression { $$ = new MathNode(BOR, $1, $3); }
- | expression '^' expression { $$ = new MathNode(BXOR, $1, $3); }
- | expression LEQ expression { $$ = new MathNode(LEQ, $1, $3); }
- | expression LNEQ expression { $$ = new MathNode(LNEQ, $1, $3); }
- | expression LAND expression { $$ = new MathNode(LAND, $1, $3); }
- | expression LOR expression { $$ = new MathNode(LOR, $1, $3); }
- | expression '<' expression { $$ = new MathNode(LT, $1, $3); }
- | expression '>' expression { $$ = new MathNode(GT, $1, $3); }
- | expression LTEQ expression { $$ = new MathNode(LTEQ, $1, $3); }
- | expression GTEQ expression { $$ = new MathNode(GTEQ, $1, $3); }
- | function_expression { $$ = $1; }
- | IF expression ':' expression ':' expression { $$ = new IfNode($2, $4, $6); }
- /* | VAR ADDADD { $$ = ast_add_math_eq_operation(ADDADD, $1, NULL); }
- | VAR SUBSUB { $$ = ast_add_math_eq_operation(SUBSUB, $1, NULL); }
- | ADDADD VAR { $$ = ast_add_math_eq_operation(ADDADD, $2, NULL); }
- | SUBSUB VAR { $$ = ast_add_math_eq_operation(SUBSUB, $2, NULL); }
- | VAR ADDEQ expression { $$ = ast_add_math_eq_operation(ADDEQ, $1, $3); }
- | VAR SUBEQ expression { $$ = ast_add_math_eq_operation(SUBEQ, $1, $3); }
- | VAR POWEQ expression { $$ = ast_add_math_eq_operation(POWEQ, $1, $3); }
- | VAR MULEQ expression { $$ = ast_add_math_eq_operation(MULEQ, $1, $3); }
- | VAR DIVEQ expression { $$ = ast_add_math_eq_operation(DIVEQ, $1, $3); }
- | VAR MODEQ expression { $$ = ast_add_math_eq_operation(MODEQ, $1, $3); }
- | VAR BANDEQ expression { $$ = ast_add_math_eq_operation(BANDEQ, $1, $3); }
- | VAR BOREQ expression { $$ = ast_add_math_eq_operation(BOREQ, $1, $3); }
- | VAR BXOREQ expression { $$ = ast_add_math_eq_operation(BXOREQ, $1, $3); }
- */
- ;
- input_list: { $$; }
- | type_statement VAR { $$.push_back(std::make_tuple($2, $1));}
- | input_list ',' type_statement VAR { $$.splice($$.begin(), $1);$$.push_back(std::make_tuple($4, $3)); }
- ;
- function_statement:
- VAR type_statement '{' block '}' { $$ = new FunctionNode($1, {}, $2, $4); }
- | VAR type_statement ':' expression ';' { $$ = new FunctionNode($1, {}, $2, $4); }
- | VAR input_list ':' type_statement ':' expression ';' { $$ = new FunctionNode($1, $2, $4, $6); }
- | VAR input_list ':' type_statement '{' block '}' { $$ = new FunctionNode($1, $2, $4, $6); }
- | VAR input_list '{' block '}' { $$ = new FunctionNode($1, $2, NONE, $4); }
- ;
- function_expression:
- VAR '(' expression_list ')' { $$ = new FunctionCallNode($1, $3); }
- | VAR '(' expression ')' {
- $$ = new FunctionCallNode($1, std::vector<AstNode*>({$3}));
- }
- ;
- if_statement:
- IF expression '{' block '}' %prec NO_ELSE { $$ = new IfNode($2, $4, NULL); }
- | IF expression ':' statement ';' %prec NO_ELSE { $$ = new IfNode($2, $4, NULL); }
- | IF expression ':' statement ';' ELSE ':' statement ';' { $$ = new IfNode($2, $4, $8); }
- | IF expression '{' block '}' ELSE '{' block '}' { $$ = new IfNode($2, $4, $8); }
- | IF expression '{' block '}' ELSE ':' statement ';' { $$ = new IfNode($2, $4, $8); }
- | IF expression ':' statement ';' ELSE '{' block '}' { $$ = new IfNode($2, $4, $8); }
- ;
- loop_statement:
- WHILE expression '{' block '}' { $$ = new LoopNode($2, $4); }
- | FOR expression ':' expression ':' expression '{' block '}' {
- $$ = new ForNode($2, $4, $6, $8);
- }
- ;
- %%
- extern void parse_error(std::string msg);
- void yy::parser::error (const std::string& msg)
- {
- parse_error(msg.c_str());
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement