196 lines
2.9 KiB
Plaintext
196 lines
2.9 KiB
Plaintext
%{
|
|
package parser
|
|
|
|
import (
|
|
"github.com/mattn/kinako/ast"
|
|
)
|
|
|
|
%}
|
|
|
|
%type<compstmt> compstmt
|
|
%type<stmts> stmts
|
|
%type<stmt> stmt
|
|
%type<expr> expr
|
|
|
|
%union{
|
|
compstmt []ast.Stmt
|
|
stmts []ast.Stmt
|
|
stmt ast.Stmt
|
|
expr ast.Expr
|
|
tok ast.Token
|
|
term ast.Token
|
|
terms ast.Token
|
|
opt_terms ast.Token
|
|
}
|
|
|
|
%token<tok> IDENT NUMBER STRING EQEQ NEQ GE LE OROR ANDAND POW
|
|
|
|
%right '='
|
|
%right '?' ':'
|
|
%left OROR
|
|
%left ANDAND
|
|
%left IDENT
|
|
%nonassoc EQEQ NEQ ','
|
|
%left '>' GE '<' LE SHIFTLEFT SHIFTRIGHT
|
|
|
|
%left '+' '-' PLUSPLUS MINUSMINUS
|
|
%left '*' '/' '%'
|
|
%right UNARY
|
|
|
|
%%
|
|
|
|
compstmt : opt_terms
|
|
{
|
|
$$ = nil
|
|
}
|
|
| stmts opt_terms
|
|
{
|
|
$$ = $1
|
|
}
|
|
|
|
stmts :
|
|
opt_terms stmt
|
|
{
|
|
$$ = []ast.Stmt{$2}
|
|
if l, ok := yylex.(*Lexer); ok {
|
|
l.stmts = $$
|
|
}
|
|
}
|
|
| stmts terms stmt
|
|
{
|
|
if $3 != nil {
|
|
$$ = append($1, $3)
|
|
if l, ok := yylex.(*Lexer); ok {
|
|
l.stmts = $$
|
|
}
|
|
}
|
|
}
|
|
|
|
stmt :
|
|
expr '=' expr
|
|
{
|
|
$$ = &ast.LetStmt{Lhs: $1, Operator: "=", Rhs: $3}
|
|
}
|
|
| expr
|
|
{
|
|
$$ = &ast.ExprStmt{Expr: $1}
|
|
}
|
|
|
|
expr :
|
|
IDENT
|
|
{
|
|
$$ = &ast.IdentExpr{Lit: $1.Lit}
|
|
}
|
|
| NUMBER
|
|
{
|
|
$$ = &ast.NumberExpr{Lit: $1.Lit}
|
|
}
|
|
| '-' expr %prec UNARY
|
|
{
|
|
$$ = &ast.UnaryExpr{Operator: "-", Expr: $2}
|
|
}
|
|
| '!' expr %prec UNARY
|
|
{
|
|
$$ = &ast.UnaryExpr{Operator: "!", Expr: $2}
|
|
}
|
|
| '^' expr %prec UNARY
|
|
{
|
|
$$ = &ast.UnaryExpr{Operator: "^", Expr: $2}
|
|
}
|
|
| STRING
|
|
{
|
|
$$ = &ast.StringExpr{Lit: $1.Lit}
|
|
}
|
|
| expr '?' expr ':' expr
|
|
{
|
|
$$ = &ast.TernaryOpExpr{Expr: $1, Lhs: $3, Rhs: $5}
|
|
}
|
|
| '(' expr ')'
|
|
{
|
|
$$ = &ast.ParenExpr{SubExpr: $2}
|
|
}
|
|
| expr '+' expr
|
|
{
|
|
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "+", Rhs: $3}
|
|
}
|
|
| expr '-' expr
|
|
{
|
|
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "-", Rhs: $3}
|
|
}
|
|
| expr '*' expr
|
|
{
|
|
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "*", Rhs: $3}
|
|
}
|
|
| expr '/' expr
|
|
{
|
|
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "/", Rhs: $3}
|
|
}
|
|
| expr '%' expr
|
|
{
|
|
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "%", Rhs: $3}
|
|
}
|
|
| expr EQEQ expr
|
|
{
|
|
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "==", Rhs: $3}
|
|
}
|
|
| expr NEQ expr
|
|
{
|
|
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "!=", Rhs: $3}
|
|
}
|
|
| expr '>' expr
|
|
{
|
|
$$ = &ast.BinOpExpr{Lhs: $1, Operator: ">", Rhs: $3}
|
|
}
|
|
| expr GE expr
|
|
{
|
|
$$ = &ast.BinOpExpr{Lhs: $1, Operator: ">=", Rhs: $3}
|
|
}
|
|
| expr '<' expr
|
|
{
|
|
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "<", Rhs: $3}
|
|
}
|
|
| expr LE expr
|
|
{
|
|
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "<=", Rhs: $3}
|
|
}
|
|
| expr '|' expr
|
|
{
|
|
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "|", Rhs: $3}
|
|
}
|
|
| expr OROR expr
|
|
{
|
|
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "||", Rhs: $3}
|
|
}
|
|
| expr '&' expr
|
|
{
|
|
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "&", Rhs: $3}
|
|
}
|
|
| expr ANDAND expr
|
|
{
|
|
$$ = &ast.BinOpExpr{Lhs: $1, Operator: "&&", Rhs: $3}
|
|
}
|
|
|
|
opt_terms : /* none */
|
|
| terms
|
|
;
|
|
|
|
|
|
terms : term
|
|
{
|
|
}
|
|
| terms term
|
|
{
|
|
}
|
|
;
|
|
|
|
term : ';'
|
|
{
|
|
}
|
|
| '\n'
|
|
{
|
|
}
|
|
;
|
|
|
|
%%
|
|
|