123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535 |
- %{
- package parse
- import (
- "github.com/yuin/gopher-lua/ast"
- )
- %}
- %type<stmts> chunk
- %type<stmts> chunk1
- %type<stmts> block
- %type<stmt> stat
- %type<stmts> elseifs
- %type<stmt> laststat
- %type<funcname> funcname
- %type<funcname> funcname1
- %type<exprlist> varlist
- %type<expr> var
- %type<namelist> namelist
- %type<exprlist> exprlist
- %type<expr> expr
- %type<expr> string
- %type<expr> prefixexp
- %type<expr> functioncall
- %type<expr> afunctioncall
- %type<exprlist> args
- %type<expr> function
- %type<funcexpr> funcbody
- %type<parlist> parlist
- %type<expr> tableconstructor
- %type<fieldlist> fieldlist
- %type<field> field
- %type<fieldsep> fieldsep
- %union {
- token ast.Token
- stmts []ast.Stmt
- stmt ast.Stmt
- funcname *ast.FuncName
- funcexpr *ast.FunctionExpr
- exprlist []ast.Expr
- expr ast.Expr
- fieldlist []*ast.Field
- field *ast.Field
- fieldsep string
- namelist []string
- parlist *ast.ParList
- }
- /* Reserved words */
- %token<token> TAnd TBreak TDo TElse TElseIf TEnd TFalse TFor TFunction TIf TIn TLocal TNil TNot TOr TReturn TRepeat TThen TTrue TUntil TWhile TGoto
- /* Literals */
- %token<token> TEqeq TNeq TLte TGte T2Comma T3Comma T2Colon TIdent TNumber TString '{' '('
- /* Operators */
- %left TOr
- %left TAnd
- %left '>' '<' TGte TLte TEqeq TNeq
- %right T2Comma
- %left '+' '-'
- %left '*' '/' '%'
- %right UNARY /* not # -(unary) */
- %right '^'
- %%
- chunk:
- chunk1 {
- $$ = $1
- if l, ok := yylex.(*Lexer); ok {
- l.Stmts = $$
- }
- } |
- chunk1 laststat {
- $$ = append($1, $2)
- if l, ok := yylex.(*Lexer); ok {
- l.Stmts = $$
- }
- } |
- chunk1 laststat ';' {
- $$ = append($1, $2)
- if l, ok := yylex.(*Lexer); ok {
- l.Stmts = $$
- }
- }
- chunk1:
- {
- $$ = []ast.Stmt{}
- } |
- chunk1 stat {
- $$ = append($1, $2)
- } |
- chunk1 ';' {
- $$ = $1
- }
- block:
- chunk {
- $$ = $1
- }
- stat:
- varlist '=' exprlist {
- $$ = &ast.AssignStmt{Lhs: $1, Rhs: $3}
- $$.SetLine($1[0].Line())
- } |
- /* 'stat = functioncal' causes a reduce/reduce conflict */
- prefixexp {
- if _, ok := $1.(*ast.FuncCallExpr); !ok {
- yylex.(*Lexer).Error("parse error")
- } else {
- $$ = &ast.FuncCallStmt{Expr: $1}
- $$.SetLine($1.Line())
- }
- } |
- TDo block TEnd {
- $$ = &ast.DoBlockStmt{Stmts: $2}
- $$.SetLine($1.Pos.Line)
- $$.SetLastLine($3.Pos.Line)
- } |
- TWhile expr TDo block TEnd {
- $$ = &ast.WhileStmt{Condition: $2, Stmts: $4}
- $$.SetLine($1.Pos.Line)
- $$.SetLastLine($5.Pos.Line)
- } |
- TRepeat block TUntil expr {
- $$ = &ast.RepeatStmt{Condition: $4, Stmts: $2}
- $$.SetLine($1.Pos.Line)
- $$.SetLastLine($4.Line())
- } |
- TIf expr TThen block elseifs TEnd {
- $$ = &ast.IfStmt{Condition: $2, Then: $4}
- cur := $$
- for _, elseif := range $5 {
- cur.(*ast.IfStmt).Else = []ast.Stmt{elseif}
- cur = elseif
- }
- $$.SetLine($1.Pos.Line)
- $$.SetLastLine($6.Pos.Line)
- } |
- TIf expr TThen block elseifs TElse block TEnd {
- $$ = &ast.IfStmt{Condition: $2, Then: $4}
- cur := $$
- for _, elseif := range $5 {
- cur.(*ast.IfStmt).Else = []ast.Stmt{elseif}
- cur = elseif
- }
- cur.(*ast.IfStmt).Else = $7
- $$.SetLine($1.Pos.Line)
- $$.SetLastLine($8.Pos.Line)
- } |
- TFor TIdent '=' expr ',' expr TDo block TEnd {
- $$ = &ast.NumberForStmt{Name: $2.Str, Init: $4, Limit: $6, Stmts: $8}
- $$.SetLine($1.Pos.Line)
- $$.SetLastLine($9.Pos.Line)
- } |
- TFor TIdent '=' expr ',' expr ',' expr TDo block TEnd {
- $$ = &ast.NumberForStmt{Name: $2.Str, Init: $4, Limit: $6, Step:$8, Stmts: $10}
- $$.SetLine($1.Pos.Line)
- $$.SetLastLine($11.Pos.Line)
- } |
- TFor namelist TIn exprlist TDo block TEnd {
- $$ = &ast.GenericForStmt{Names:$2, Exprs:$4, Stmts: $6}
- $$.SetLine($1.Pos.Line)
- $$.SetLastLine($7.Pos.Line)
- } |
- TFunction funcname funcbody {
- $$ = &ast.FuncDefStmt{Name: $2, Func: $3}
- $$.SetLine($1.Pos.Line)
- $$.SetLastLine($3.LastLine())
- } |
- TLocal TFunction TIdent funcbody {
- $$ = &ast.LocalAssignStmt{Names:[]string{$3.Str}, Exprs: []ast.Expr{$4}}
- $$.SetLine($1.Pos.Line)
- $$.SetLastLine($4.LastLine())
- } |
- TLocal namelist '=' exprlist {
- $$ = &ast.LocalAssignStmt{Names: $2, Exprs:$4}
- $$.SetLine($1.Pos.Line)
- } |
- TLocal namelist {
- $$ = &ast.LocalAssignStmt{Names: $2, Exprs:[]ast.Expr{}}
- $$.SetLine($1.Pos.Line)
- } |
- T2Colon TIdent T2Colon {
- $$ = &ast.LabelStmt{Name: $2.Str}
- $$.SetLine($1.Pos.Line)
- } |
- TGoto TIdent {
- $$ = &ast.GotoStmt{Label: $2.Str}
- $$.SetLine($1.Pos.Line)
- }
- elseifs:
- {
- $$ = []ast.Stmt{}
- } |
- elseifs TElseIf expr TThen block {
- $$ = append($1, &ast.IfStmt{Condition: $3, Then: $5})
- $$[len($$)-1].SetLine($2.Pos.Line)
- }
- laststat:
- TReturn {
- $$ = &ast.ReturnStmt{Exprs:nil}
- $$.SetLine($1.Pos.Line)
- } |
- TReturn exprlist {
- $$ = &ast.ReturnStmt{Exprs:$2}
- $$.SetLine($1.Pos.Line)
- } |
- TBreak {
- $$ = &ast.BreakStmt{}
- $$.SetLine($1.Pos.Line)
- }
- funcname:
- funcname1 {
- $$ = $1
- } |
- funcname1 ':' TIdent {
- $$ = &ast.FuncName{Func:nil, Receiver:$1.Func, Method: $3.Str}
- }
- funcname1:
- TIdent {
- $$ = &ast.FuncName{Func: &ast.IdentExpr{Value:$1.Str}}
- $$.Func.SetLine($1.Pos.Line)
- } |
- funcname1 '.' TIdent {
- key:= &ast.StringExpr{Value:$3.Str}
- key.SetLine($3.Pos.Line)
- fn := &ast.AttrGetExpr{Object: $1.Func, Key: key}
- fn.SetLine($3.Pos.Line)
- $$ = &ast.FuncName{Func: fn}
- }
- varlist:
- var {
- $$ = []ast.Expr{$1}
- } |
- varlist ',' var {
- $$ = append($1, $3)
- }
- var:
- TIdent {
- $$ = &ast.IdentExpr{Value:$1.Str}
- $$.SetLine($1.Pos.Line)
- } |
- prefixexp '[' expr ']' {
- $$ = &ast.AttrGetExpr{Object: $1, Key: $3}
- $$.SetLine($1.Line())
- } |
- prefixexp '.' TIdent {
- key := &ast.StringExpr{Value:$3.Str}
- key.SetLine($3.Pos.Line)
- $$ = &ast.AttrGetExpr{Object: $1, Key: key}
- $$.SetLine($1.Line())
- }
- namelist:
- TIdent {
- $$ = []string{$1.Str}
- } |
- namelist ',' TIdent {
- $$ = append($1, $3.Str)
- }
- exprlist:
- expr {
- $$ = []ast.Expr{$1}
- } |
- exprlist ',' expr {
- $$ = append($1, $3)
- }
- expr:
- TNil {
- $$ = &ast.NilExpr{}
- $$.SetLine($1.Pos.Line)
- } |
- TFalse {
- $$ = &ast.FalseExpr{}
- $$.SetLine($1.Pos.Line)
- } |
- TTrue {
- $$ = &ast.TrueExpr{}
- $$.SetLine($1.Pos.Line)
- } |
- TNumber {
- $$ = &ast.NumberExpr{Value: $1.Str}
- $$.SetLine($1.Pos.Line)
- } |
- T3Comma {
- $$ = &ast.Comma3Expr{}
- $$.SetLine($1.Pos.Line)
- } |
- function {
- $$ = $1
- } |
- prefixexp {
- $$ = $1
- } |
- string {
- $$ = $1
- } |
- tableconstructor {
- $$ = $1
- } |
- expr TOr expr {
- $$ = &ast.LogicalOpExpr{Lhs: $1, Operator: "or", Rhs: $3}
- $$.SetLine($1.Line())
- } |
- expr TAnd expr {
- $$ = &ast.LogicalOpExpr{Lhs: $1, Operator: "and", Rhs: $3}
- $$.SetLine($1.Line())
- } |
- expr '>' expr {
- $$ = &ast.RelationalOpExpr{Lhs: $1, Operator: ">", Rhs: $3}
- $$.SetLine($1.Line())
- } |
- expr '<' expr {
- $$ = &ast.RelationalOpExpr{Lhs: $1, Operator: "<", Rhs: $3}
- $$.SetLine($1.Line())
- } |
- expr TGte expr {
- $$ = &ast.RelationalOpExpr{Lhs: $1, Operator: ">=", Rhs: $3}
- $$.SetLine($1.Line())
- } |
- expr TLte expr {
- $$ = &ast.RelationalOpExpr{Lhs: $1, Operator: "<=", Rhs: $3}
- $$.SetLine($1.Line())
- } |
- expr TEqeq expr {
- $$ = &ast.RelationalOpExpr{Lhs: $1, Operator: "==", Rhs: $3}
- $$.SetLine($1.Line())
- } |
- expr TNeq expr {
- $$ = &ast.RelationalOpExpr{Lhs: $1, Operator: "~=", Rhs: $3}
- $$.SetLine($1.Line())
- } |
- expr T2Comma expr {
- $$ = &ast.StringConcatOpExpr{Lhs: $1, Rhs: $3}
- $$.SetLine($1.Line())
- } |
- expr '+' expr {
- $$ = &ast.ArithmeticOpExpr{Lhs: $1, Operator: "+", Rhs: $3}
- $$.SetLine($1.Line())
- } |
- expr '-' expr {
- $$ = &ast.ArithmeticOpExpr{Lhs: $1, Operator: "-", Rhs: $3}
- $$.SetLine($1.Line())
- } |
- expr '*' expr {
- $$ = &ast.ArithmeticOpExpr{Lhs: $1, Operator: "*", Rhs: $3}
- $$.SetLine($1.Line())
- } |
- expr '/' expr {
- $$ = &ast.ArithmeticOpExpr{Lhs: $1, Operator: "/", Rhs: $3}
- $$.SetLine($1.Line())
- } |
- expr '%' expr {
- $$ = &ast.ArithmeticOpExpr{Lhs: $1, Operator: "%", Rhs: $3}
- $$.SetLine($1.Line())
- } |
- expr '^' expr {
- $$ = &ast.ArithmeticOpExpr{Lhs: $1, Operator: "^", Rhs: $3}
- $$.SetLine($1.Line())
- } |
- '-' expr %prec UNARY {
- $$ = &ast.UnaryMinusOpExpr{Expr: $2}
- $$.SetLine($2.Line())
- } |
- TNot expr %prec UNARY {
- $$ = &ast.UnaryNotOpExpr{Expr: $2}
- $$.SetLine($2.Line())
- } |
- '#' expr %prec UNARY {
- $$ = &ast.UnaryLenOpExpr{Expr: $2}
- $$.SetLine($2.Line())
- }
- string:
- TString {
- $$ = &ast.StringExpr{Value: $1.Str}
- $$.SetLine($1.Pos.Line)
- }
- prefixexp:
- var {
- $$ = $1
- } |
- afunctioncall {
- $$ = $1
- } |
- functioncall {
- $$ = $1
- } |
- '(' expr ')' {
- if ex, ok := $2.(*ast.Comma3Expr); ok {
- ex.AdjustRet = true
- }
- $$ = $2
- $$.SetLine($1.Pos.Line)
- }
- afunctioncall:
- '(' functioncall ')' {
- $2.(*ast.FuncCallExpr).AdjustRet = true
- $$ = $2
- }
- functioncall:
- prefixexp args {
- $$ = &ast.FuncCallExpr{Func: $1, Args: $2}
- $$.SetLine($1.Line())
- } |
- prefixexp ':' TIdent args {
- $$ = &ast.FuncCallExpr{Method: $3.Str, Receiver: $1, Args: $4}
- $$.SetLine($1.Line())
- }
- args:
- '(' ')' {
- if yylex.(*Lexer).PNewLine {
- yylex.(*Lexer).TokenError($1, "ambiguous syntax (function call x new statement)")
- }
- $$ = []ast.Expr{}
- } |
- '(' exprlist ')' {
- if yylex.(*Lexer).PNewLine {
- yylex.(*Lexer).TokenError($1, "ambiguous syntax (function call x new statement)")
- }
- $$ = $2
- } |
- tableconstructor {
- $$ = []ast.Expr{$1}
- } |
- string {
- $$ = []ast.Expr{$1}
- }
- function:
- TFunction funcbody {
- $$ = &ast.FunctionExpr{ParList:$2.ParList, Stmts: $2.Stmts}
- $$.SetLine($1.Pos.Line)
- $$.SetLastLine($2.LastLine())
- }
- funcbody:
- '(' parlist ')' block TEnd {
- $$ = &ast.FunctionExpr{ParList: $2, Stmts: $4}
- $$.SetLine($1.Pos.Line)
- $$.SetLastLine($5.Pos.Line)
- } |
- '(' ')' block TEnd {
- $$ = &ast.FunctionExpr{ParList: &ast.ParList{HasVargs: false, Names: []string{}}, Stmts: $3}
- $$.SetLine($1.Pos.Line)
- $$.SetLastLine($4.Pos.Line)
- }
- parlist:
- T3Comma {
- $$ = &ast.ParList{HasVargs: true, Names: []string{}}
- } |
- namelist {
- $$ = &ast.ParList{HasVargs: false, Names: []string{}}
- $$.Names = append($$.Names, $1...)
- } |
- namelist ',' T3Comma {
- $$ = &ast.ParList{HasVargs: true, Names: []string{}}
- $$.Names = append($$.Names, $1...)
- }
- tableconstructor:
- '{' '}' {
- $$ = &ast.TableExpr{Fields: []*ast.Field{}}
- $$.SetLine($1.Pos.Line)
- } |
- '{' fieldlist '}' {
- $$ = &ast.TableExpr{Fields: $2}
- $$.SetLine($1.Pos.Line)
- }
- fieldlist:
- field {
- $$ = []*ast.Field{$1}
- } |
- fieldlist fieldsep field {
- $$ = append($1, $3)
- } |
- fieldlist fieldsep {
- $$ = $1
- }
- field:
- TIdent '=' expr {
- $$ = &ast.Field{Key: &ast.StringExpr{Value:$1.Str}, Value: $3}
- $$.Key.SetLine($1.Pos.Line)
- } |
- '[' expr ']' '=' expr {
- $$ = &ast.Field{Key: $2, Value: $5}
- } |
- expr {
- $$ = &ast.Field{Value: $1}
- }
- fieldsep:
- ',' {
- $$ = ","
- } |
- ';' {
- $$ = ";"
- }
- %%
- func TokenName(c int) string {
- if c >= TAnd && c-TAnd < len(yyToknames) {
- if yyToknames[c-TAnd] != "" {
- return yyToknames[c-TAnd]
- }
- }
- return string([]byte{byte(c)})
- }
|