187 lines
7.1 KiB
Text
187 lines
7.1 KiB
Text
%skeleton "lalr1.cc"
|
|
%require "3.0"
|
|
%defines
|
|
%define api.value.type variant
|
|
%define api.token.raw
|
|
%define api.parser.class { parser }
|
|
%define api.namespace { yy }
|
|
%define api.token.prefix {TOK_}
|
|
%define parse.trace
|
|
|
|
|
|
%code requires {
|
|
#include <string>
|
|
#include "ast.hpp"
|
|
class Scanner;
|
|
}
|
|
|
|
%code {
|
|
#include <iostream>
|
|
#include "scanner.hpp"
|
|
|
|
#undef yylex
|
|
#define yylex scanner->lex
|
|
}
|
|
|
|
%parse-param { Scanner* scanner }
|
|
%parse-param { std::unique_ptr<Module>* result }
|
|
|
|
%token <std::string> IDENTIFIER STRING
|
|
%token <std::string> NUMBER
|
|
|
|
%left KW_OR
|
|
%left KW_AND
|
|
%right KW_NOT // unary logical NOT
|
|
%token KW_DEF KW_IF KW_RETURN KW_FOR KW_IN KW_PASS KW_ELSE KW_ELIF KW_CLASS KW_WHILE KW_BREAK KW_CONTINUE
|
|
|
|
%token L_PAREN R_PAREN L_BRACKET R_BRACKET L_BRACE R_BRACE
|
|
%token DOT COLON SEMICOLON COMMA
|
|
%token INDENT DEDENT NEWLINE EOF
|
|
|
|
%left BIT_OR
|
|
%left BIT_XOR
|
|
%left BIT_AND
|
|
%left LSHIFT RSHIFT
|
|
%token BIT_NOT
|
|
|
|
%nonassoc EQ NE LT LTE GT GTE
|
|
|
|
%left PLUS MINUS
|
|
%left MULTIPLY DIVIDE MODULO
|
|
%left POWER
|
|
|
|
%right ASSIGN PLUS_ASSIGN MINUS_ASSIGN MULTIPLY_ASSIGN DIVIDE_ASSIGN MODULO_ASSIGN
|
|
%right BIT_AND_ASSIGN BIT_OR_ASSIGN BIT_XOR_ASSIGN LSHIFT_ASSIGN RSHIFT_ASSIGN
|
|
|
|
%type <std::unique_ptr<Expr>> expr
|
|
%type <std::unique_ptr<Expr>> opt_expr
|
|
%type <std::unique_ptr<Slice>> slice
|
|
%type <std::unique_ptr<Stmt>> stmt
|
|
%type <std::vector<std::unique_ptr<Expr>>> args
|
|
%type <std::vector<std::unique_ptr<Expr>>> tuple
|
|
%type <std::vector<std::unique_ptr<Stmt>>> stmt_list
|
|
%type <std::vector<std::string>> params
|
|
%type <std::vector<std::unique_ptr<Stmt>>> elif_chain
|
|
|
|
|
|
%%
|
|
input:
|
|
stmt_list EOF { *result = std::make_unique<Module>(std::move($1));}
|
|
;
|
|
|
|
stmt_list:
|
|
/* empty */ { $$ = std::vector<std::unique_ptr<Stmt>>(); }
|
|
| stmt_list stmt { $1.push_back(std::move($2)); $$ = std::move($1); }
|
|
;
|
|
|
|
stmt:
|
|
expr NEWLINE {
|
|
$$ = std::make_unique<ExprStmt>(std::move($1));
|
|
}
|
|
| expr ASSIGN expr NEWLINE {
|
|
$$ = std::make_unique<Assign>(std::move($1), std::move($3));
|
|
}
|
|
| KW_IF expr COLON NEWLINE INDENT stmt_list DEDENT elif_chain{
|
|
$$ = std::make_unique<If>(std::move($2), std::move($6), std::move($8));
|
|
}
|
|
| KW_FOR IDENTIFIER KW_IN expr COLON NEWLINE INDENT stmt_list DEDENT {
|
|
$$ = std::make_unique<For> ($2, std::move($4), std::move($8));
|
|
}
|
|
| KW_DEF IDENTIFIER L_PAREN params R_PAREN COLON NEWLINE INDENT stmt_list DEDENT {
|
|
$$ = std::make_unique<FunctionDef>($2, std::move($4), std::move($9));
|
|
}
|
|
| KW_RETURN expr NEWLINE {
|
|
$$ = std::make_unique<Return>(std::move($2));
|
|
}
|
|
| KW_RETURN NEWLINE {
|
|
$$ = std::make_unique<Return>(nullptr);
|
|
}
|
|
| KW_PASS NEWLINE {
|
|
$$ = std::make_unique<Pass>();
|
|
}
|
|
| KW_BREAK NEWLINE {
|
|
$$ = std::make_unique<Break>();
|
|
}
|
|
| KW_CONTINUE NEWLINE {
|
|
$$ = std::make_unique<Continue>();
|
|
}
|
|
| KW_WHILE expr COLON NEWLINE INDENT stmt_list DEDENT {
|
|
$$ = std::make_unique<While>(std::move($2), std::move($6));
|
|
}
|
|
| KW_CLASS IDENTIFIER COLON NEWLINE INDENT stmt_list DEDENT {
|
|
$$ = std::make_unique<ClassDef>(std::move($2), std::move($6));
|
|
}
|
|
;
|
|
|
|
expr:
|
|
NUMBER { $$ = std::make_unique<Number>($1); }
|
|
| IDENTIFIER { $$ = std::make_unique<Identifier>($1); }
|
|
| STRING { $$ = std::make_unique<String>($1); }
|
|
| expr PLUS expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::ADD), std::move($1), std::move($3)); }
|
|
| expr MULTIPLY expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::MUL), std::move($1), std::move($3)); }
|
|
| expr MINUS expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::SUB), std::move($1), std::move($3)); }
|
|
| expr LT expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::LT) , std::move($1), std::move($3)); }
|
|
| expr KW_AND expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::AND) , std::move($1), std::move($3)); }
|
|
| expr KW_OR expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::OR) , std::move($1), std::move($3)); }
|
|
| expr LTE expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::LTE) , std::move($1), std::move($3)); }
|
|
| expr POWER expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::POWER) , std::move($1), std::move($3)); }
|
|
| expr MODULO expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::MOD) , std::move($1), std::move($3)); }
|
|
| expr EQ expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::EQ) , std::move($1), std::move($3)); }
|
|
| expr DIVIDE expr { $$ = std::make_unique<BinOp>( BinaryOperator(BinaryOperator::DIV) , std::move($1), std::move($3)); }
|
|
| KW_NOT expr { $$ = std::make_unique<UnaryOpExpr>( UnaryOperator(UnaryOperator::NOT) , std::move($2)); }
|
|
| expr L_BRACKET expr R_BRACKET { $$ = std::make_unique<Subscript>(std::move($1), std::move($3));}
|
|
| expr L_BRACKET slice R_BRACKET{ $$ = std::make_unique<SliceSubscript>(std::move($1), std::move($3)); }
|
|
| L_PAREN expr R_PAREN {$$ = std::move($2); }
|
|
| expr L_PAREN args R_PAREN { $$ = std::make_unique<Call>(std::move($1), std::move($3));}
|
|
| expr DOT IDENTIFIER { $$ = std::make_unique<Attribute>(std::move($1), $3);}
|
|
| L_BRACKET args R_BRACKET { $$ = std::make_unique<List>(std::move($2));}
|
|
| L_PAREN tuple R_PAREN { $$ = std::make_unique<Tuple>(std::move($2));}
|
|
| MINUS expr { $$ = std::make_unique<UnaryOpExpr>(UnaryOperator(UnaryOperator::NEG), std::move($2));}
|
|
;
|
|
|
|
slice:
|
|
opt_expr COLON opt_expr
|
|
{ $$ = std::make_unique<Slice>(std::move($1), std::move($3), nullptr); }
|
|
| opt_expr COLON opt_expr COLON opt_expr
|
|
{ $$ = std::make_unique<Slice>(std::move($1), std::move($3), std::move($5)); }
|
|
;
|
|
|
|
opt_expr:
|
|
{ $$ = nullptr;}
|
|
| expr { $$ = std::move($1);}
|
|
|
|
args:
|
|
/* empty */ { $$ = std::vector<std::unique_ptr<Expr>>(); }
|
|
| expr { $$ = std::vector<std::unique_ptr<Expr>>();
|
|
$$.push_back(std::move($1)); }
|
|
| args COMMA expr { $1.push_back(std::move($3)); $$ = std::move($1); }
|
|
;
|
|
|
|
tuple:
|
|
expr { $$ = std::vector<std::unique_ptr<Expr>>();
|
|
$$.push_back(std::move($1)); }
|
|
| tuple COMMA expr { $1.push_back(std::move($3)); $$ = std::move($1); }
|
|
|
|
params:
|
|
{ $$ = std::vector<std::string>();}
|
|
| IDENTIFIER { $$ = std::vector<std::string>(); $$.push_back($1); }
|
|
| params COMMA IDENTIFIER {$1.push_back($3); $$ = std::move($1);}
|
|
|
|
elif_chain:
|
|
/* empty */ { $$ = std::vector<std::unique_ptr<Stmt>>(); }
|
|
| KW_ELIF expr COLON NEWLINE INDENT stmt_list DEDENT elif_chain {
|
|
std::vector<std::unique_ptr<Stmt>> output;
|
|
output.push_back(std::make_unique<If>(std::move($2), std::move($6), std::move($8)));
|
|
$$ = std::move(output);
|
|
}
|
|
| KW_ELSE COLON NEWLINE INDENT stmt_list DEDENT {
|
|
$$ = std::move($5);
|
|
}
|
|
;
|
|
%%
|
|
namespace yy {
|
|
void parser::error(const std::string& msg)
|
|
{
|
|
std::cerr << "Error: " << msg << "\n";
|
|
}
|
|
}
|