Untitled
unknown
plain_text
2 years ago
3.8 kB
6
Indexable
%skeleton "lalr1.cc" %require "2.5" %defines %define api.namespace {calc} %define api.value.type variant %define api.parser.class {Parser} %code requires { #include <iostream> #include <memory> #include "ast.h" namespace calc {class Lexer;} } %parse-param {calc::Lexer& lexer} {std::shared_ptr<Ast>& result} {std::string& message} %code { #include "lexer.h" #define yylex lexer.lex } %token END 0 "end of file" %token ERROR %token EOL "\n" %token <int> NUM %token <std::string> NAME %token ASSIGN "=" %token PLUS "+" %token MINUS "-" %token MUL "*" %token DIV "/" %token LPAR "(" %token RPAR ")" %token FUNC "def" %token COLON ":" %token COMMA "," %token DO "do" %token DONE "done" %token IF "if" %token ELSE "else" %token WHILE "while" %token OR "||" %token AND "&&" %token NOT "!" %token EQUAL "==" %token NOT_EQUAL "!=" %token LESS "<" %token LESS_OR_EQUAL "<=" %token GREATER ">" %token GREATER_OR_EQUAL ">=" %type <std::shared_ptr<Ast>> expr stmt %type <std::vector<std::string>> params %type <std::vector<std::shared_ptr<Ast>>> arguments %type <std::vector<std::shared_ptr<Ast>>> block %left "+" "-" %left "*" "/" %left "||" %left "&&" %left "==" "!=" "<" "<=" ">" ">=" %nonassoc UMINUS %nonassoc NOT_EXPR %right "then" "else" %% input: stmt "\n" { result = $1; } ; params : NAME { $$ = std::vector<std::string>{$1}; } | params "," NAME { $1.push_back($3); $$ = std::move($1); } ; arguments : expr { $$ = std::vector<std::shared_ptr<Ast>>{$1}; } | arguments "," expr { $1.push_back($3); $$ = std::move($1); } ; block : stmt { $$ = std::vector<std::shared_ptr<Ast>>{$1}; } | block "\n" stmt { $1.push_back($3); $$ = std::move($1); } ; stmt: expr { $$ = $1; } | "def" NAME "(" params ")" ":" stmt { $$ = new_definition($2, $4, std::vector<std::shared_ptr<Ast>>{$7}); } | "def" NAME "(" params ")" ":" "do" "\n" block "\n" "done" {$$ = new_definition($2, $4, $9); } | NAME "=" expr { $$ = new_assignment($1, $3); } | NAME "(" arguments ")" { $$ = new_function($1, $3); } | "if" expr ":" "do" "\n" block "\n" "done" %prec "then" { $$ = new_condition($2, $6); } | "if" expr ":" stmt %prec "then" { $$ = new_condition($2, std::vector<std::shared_ptr<Ast>>{$4}); } | "if" expr ":" stmt "\n" "else" ":" stmt { $$ = new_condition($2, std::vector<std::shared_ptr<Ast>>{$4}, std::vector<std::shared_ptr<Ast>>{$8}); } | "if" expr ":" "do" "\n" block "\n" "done" "\n" "else" ":" "do" "\n" block "\n" "done" { $$ = new_condition($2, $6, $14); } | "while" stmt ":" stmt { $$ = new_while($2, std::vector<std::shared_ptr<Ast>>{$4}); } | "while" stmt ":" "do" "\n" block "\n" "done" { $$ = new_while($2, $6); } ; expr: NUM { $$ = new_number($1); } | NAME { $$ = new_variable($1); } | expr "+" expr { $$ = new_binary(Opcode::plus, $1, $3); } | expr "-" expr { $$ = new_binary(Opcode::minus, $1, $3); } | expr "*" expr { $$ = new_binary(Opcode::mul, $1, $3); } | expr "/" expr { $$ = new_binary(Opcode::div, $1, $3); } | "(" expr ")" { $$ = $2; } | "-" %prec UMINUS expr { $$ = new_unary(Opcode::uminus, $2); } | expr "||" expr { $$ = new_binary(Opcode::or_expr, $1, $3); } | expr "&&" expr { $$ = new_binary(Opcode::and_expr, $1, $3); } | "!" %prec NOT_EXPR expr { $$ = new_unary(Opcode::not_expr, $2); } | expr "==" expr { $$ = new_binary(Opcode::equal, $1, $3); } | expr "!=" expr { $$ = new_binary(Opcode::not_equal, $1, $3); } | expr "<" expr { $$ = new_binary(Opcode::less, $1, $3); } | expr "<=" expr { $$ = new_binary(Opcode::less_or_equal, $1, $3); } | expr ">" expr { $$ = new_binary(Opcode::greater, $1, $3); } | expr ">=" expr { $$ = new_binary(Opcode::greater_or_equal, $1, $3); } ; %% void calc::Parser::error(const std::string& err) { message = err; }
Editor is loading...