1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090 |
- %{
- package parser
- import (
- "github.com/mattn/anko/ast"
- )
- %}
- %type<compstmt> compstmt
- %type<stmts> stmts
- %type<stmt> stmt
- %type<stmt_var_or_lets> stmt_var_or_lets
- %type<stmt_var> stmt_var
- %type<stmt_lets> stmt_lets
- %type<stmt_if> stmt_if
- %type<stmt_for> stmt_for
- %type<stmt_switch> stmt_switch
- %type<stmt_switch_cases> stmt_switch_cases
- %type<stmt_switch_case> stmt_switch_case
- %type<stmt_switch_default> stmt_switch_default
- %type<exprs> exprs
- %type<expr> expr
- %type<expr_idents> expr_idents
- %type<type_data> type_data
- %type<type_data_struct> type_data_struct
- %type<slice_count> slice_count
- %type<expr_member_or_ident> expr_member_or_ident
- %type<expr_member> expr_member
- %type<expr_ident> expr_ident
- %type<expr_literals> expr_literals
- %type<expr_map> expr_map
- %type<expr_slice> expr_slice
- %type<expr_chan> expr_chan
- %type<expr> expr_unary
- %type<expr> expr_binary
- %type<expr> expr_lets
- %type<expr> op_binary
- %type<expr> op_comparison
- %type<expr> op_add
- %type<expr> op_multiply
- %union{
- tok ast.Token
- compstmt ast.Stmt
- stmts ast.Stmt
- stmt ast.Stmt
- stmt_var_or_lets ast.Stmt
- stmt_var ast.Stmt
- stmt_lets ast.Stmt
- stmt_if ast.Stmt
- stmt_for ast.Stmt
- stmt_switch ast.Stmt
- stmt_switch_cases ast.Stmt
- stmt_switch_case ast.Stmt
- stmt_switch_default ast.Stmt
- exprs []ast.Expr
- expr ast.Expr
- expr_idents []string
- type_data *ast.TypeStruct
- type_data_struct *ast.TypeStruct
- slice_count int
- expr_member_or_ident ast.Expr
- expr_member *ast.MemberExpr
- expr_ident *ast.IdentExpr
- expr_literals ast.Expr
- expr_map *ast.MapExpr
- expr_slice ast.Expr
- expr_chan ast.Expr
- expr_unary ast.Expr
- expr_binary ast.Expr
- expr_lets ast.Expr
- op_binary ast.Operator
- op_comparison ast.Operator
- op_add ast.Operator
- op_multiply ast.Operator
- }
- %token<tok> IDENT NUMBER STRING ARRAY VARARG FUNC RETURN VAR THROW IF ELSE FOR IN EQEQ NEQ GE LE OROR ANDAND NEW TRUE FALSE NIL NILCOALESCE MODULE TRY CATCH FINALLY PLUSEQ MINUSEQ MULEQ DIVEQ ANDEQ OREQ BREAK CONTINUE PLUSPLUS MINUSMINUS SHIFTLEFT SHIFTRIGHT SWITCH CASE DEFAULT GO CHAN STRUCT MAKE OPCHAN EQOPCHAN TYPE LEN DELETE CLOSE MAP IMPORT
- /* lowest precedence */
- %left ,
- %right '=' PLUSEQ MINUSEQ MULEQ DIVEQ ANDEQ OREQ EQOPCHAN
- %right ':'
- %right OPCHAN
- %right '?' NILCOALESCE
- %left OROR
- %left ANDAND
- %left EQEQ NEQ '<' LE '>' GE
- %left '+' '-' '|' '^'
- %left '*' '/' '%' SHIFTLEFT SHIFTRIGHT '&'
- %right IN
- %right PLUSPLUS MINUSMINUS
- %right UNARY
- /* highest precedence */
- /* https://golang.org/ref/spec#Expression */
- %%
- compstmt :
- opt_term
- {
- $$ = nil
- }
- | stmts opt_term
- {
- $$ = $1
- }
- stmts :
- opt_term stmt
- {
- if $2 != nil {
- $$ = &ast.StmtsStmt{Stmts: []ast.Stmt{$2}}
- }
- if l, ok := yylex.(*Lexer); ok {
- l.stmt = $$
- }
- }
- | stmts term stmt
- {
- if $3 != nil {
- if $1 == nil {
- $$ = &ast.StmtsStmt{Stmts: []ast.Stmt{$3}}
- } else {
- stmts := $1.(*ast.StmtsStmt)
- stmts.Stmts = append(stmts.Stmts, $3)
- }
- if l, ok := yylex.(*Lexer); ok {
- l.stmt = $$
- }
- }
- }
- stmt :
- /* nothing */
- {
- $$ = nil
- }
- | stmt_var_or_lets
- {
- $$ = $1
- }
- | BREAK
- {
- $$ = &ast.BreakStmt{}
- $$.SetPosition($1.Position())
- }
- | CONTINUE
- {
- $$ = &ast.ContinueStmt{}
- $$.SetPosition($1.Position())
- }
- | RETURN exprs
- {
- $$ = &ast.ReturnStmt{Exprs: $2}
- $$.SetPosition($1.Position())
- }
- | THROW expr
- {
- $$ = &ast.ThrowStmt{Expr: $2}
- $$.SetPosition($1.Position())
- }
- | MODULE IDENT '{' compstmt '}'
- {
- $$ = &ast.ModuleStmt{Name: $2.Lit, Stmt: $4}
- $$.SetPosition($1.Position())
- }
- | TRY '{' compstmt '}' CATCH IDENT '{' compstmt '}' FINALLY '{' compstmt '}'
- {
- $$ = &ast.TryStmt{Try: $3, Var: $6.Lit, Catch: $8, Finally: $12}
- $$.SetPosition($1.Position())
- }
- | TRY '{' compstmt '}' CATCH '{' compstmt '}' FINALLY '{' compstmt '}'
- {
- $$ = &ast.TryStmt{Try: $3, Catch: $7, Finally: $11}
- $$.SetPosition($1.Position())
- }
- | TRY '{' compstmt '}' CATCH IDENT '{' compstmt '}'
- {
- $$ = &ast.TryStmt{Try: $3, Var: $6.Lit, Catch: $8}
- $$.SetPosition($1.Position())
- }
- | TRY '{' compstmt '}' CATCH '{' compstmt '}'
- {
- $$ = &ast.TryStmt{Try: $3, Catch: $7}
- $$.SetPosition($1.Position())
- }
- | GO IDENT '(' exprs VARARG ')'
- {
- $$ = &ast.GoroutineStmt{Expr: &ast.CallExpr{Name: $2.Lit, SubExprs: $4, VarArg: true, Go: true}}
- $$.SetPosition($2.Position())
- }
- | GO IDENT '(' exprs ')'
- {
- $$ = &ast.GoroutineStmt{Expr: &ast.CallExpr{Name: $2.Lit, SubExprs: $4, Go: true}}
- $$.SetPosition($2.Position())
- }
- | GO expr '(' exprs VARARG ')'
- {
- $$ = &ast.GoroutineStmt{Expr: &ast.AnonCallExpr{Expr: $2, SubExprs: $4, VarArg: true, Go: true}}
- $$.SetPosition($2.Position())
- }
- | GO expr '(' exprs ')'
- {
- $$ = &ast.GoroutineStmt{Expr: &ast.AnonCallExpr{Expr: $2, SubExprs: $4, Go: true}}
- $$.SetPosition($1.Position())
- }
- | DELETE '(' expr ')'
- {
- $$ = &ast.DeleteStmt{Item: $3}
- $$.SetPosition($1.Position())
- }
- | DELETE '(' expr ',' expr ')'
- {
- $$ = &ast.DeleteStmt{Item: $3, Key: $5}
- $$.SetPosition($1.Position())
- }
- | CLOSE '(' expr ')'
- {
- $$ = &ast.CloseStmt{Expr: $3}
- $$.SetPosition($1.Position())
- }
- | stmt_if
- {
- $$ = $1
- }
- | stmt_for
- {
- $$ = $1
- }
- | stmt_switch
- {
- $$ = $1
- }
- | expr
- {
- $$ = &ast.ExprStmt{Expr: $1}
- $$.SetPosition($1.Position())
- }
- stmt_var_or_lets :
- stmt_var
- {
- $$ = $1
- }
- | stmt_lets
- {
- $$ = $1
- }
- stmt_var :
- VAR expr_idents '=' exprs
- {
- $$ = &ast.VarStmt{Names: $2, Exprs: $4}
- $$.SetPosition($1.Position())
- }
- stmt_lets :
- expr '=' expr
- {
- $$ = &ast.LetsStmt{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{$3}}
- $$.SetPosition($1.Position())
- }
- | exprs '=' exprs
- {
- if len($1) == 2 && len($3) == 1 {
- if _, ok := $3[0].(*ast.ItemExpr); ok {
- $$ = &ast.LetMapItemStmt{LHSS: $1, RHS: $3[0]}
- } else {
- $$ = &ast.LetsStmt{LHSS: $1, RHSS: $3}
- }
- } else {
- $$ = &ast.LetsStmt{LHSS: $1, RHSS: $3}
- }
- $$.SetPosition($1[0].Position())
- }
- | expr EQOPCHAN expr
- {
- $$ = &ast.ChanStmt{LHS: $1, RHS: $3}
- $$.SetPosition($1.Position())
- }
- | exprs EQOPCHAN expr
- {
- if len($1) == 2 {
- chanStmt := &ast.ChanStmt{LHS: $1[0].(ast.Expr), OkExpr: $1[1].(ast.Expr), RHS: $3}
- $$ = chanStmt
- $$.SetPosition(chanStmt.LHS.Position())
- } else if len($1) < 2 {
- yylex.Error("missing expressions on left side of channel operator")
- $$ = &ast.ChanStmt{RHS: $3}
- $$.SetPosition($2.Position())
- }
- }
- stmt_if :
- IF expr '{' compstmt '}'
- {
- $$ = &ast.IfStmt{If: $2, Then: $4, Else: nil}
- $$.SetPosition($1.Position())
- }
- | stmt_if ELSE IF expr '{' compstmt '}'
- {
- ifStmt := $1.(*ast.IfStmt)
- ifStmt.ElseIf = append(ifStmt.ElseIf, &ast.IfStmt{If: $4, Then: $6})
- }
- | stmt_if ELSE '{' compstmt '}'
- {
- ifStmt := $1.(*ast.IfStmt)
- if ifStmt.Else != nil {
- yylex.Error("multiple else statement")
- }
- ifStmt.Else = $4
- }
- stmt_for :
- FOR '{' compstmt '}'
- {
- $$ = &ast.LoopStmt{Stmt: $3}
- $$.SetPosition($1.Position())
- }
- | FOR expr_idents IN expr '{' compstmt '}'
- {
- if len($2) < 1 {
- yylex.Error("missing identifier")
- } else if len($2) > 2 {
- yylex.Error("too many identifiers")
- } else {
- $$ = &ast.ForStmt{Vars: $2, Value: $4, Stmt: $6}
- $$.SetPosition($1.Position())
- }
- }
- | FOR expr '{' compstmt '}'
- {
- $$ = &ast.LoopStmt{Expr: $2, Stmt: $4}
- $$.SetPosition($1.Position())
- }
- | FOR ';' ';' '{' compstmt '}'
- {
- $$ = &ast.CForStmt{Stmt: $5}
- $$.SetPosition($1.Position())
- }
- | FOR ';' ';' expr '{' compstmt '}'
- {
- $$ = &ast.CForStmt{Expr3: $4, Stmt: $6}
- $$.SetPosition($1.Position())
- }
- | FOR ';' expr ';' '{' compstmt '}'
- {
- $$ = &ast.CForStmt{Expr2: $3, Stmt: $6}
- $$.SetPosition($1.Position())
- }
- | FOR ';' expr ';' expr '{' compstmt '}'
- {
- $$ = &ast.CForStmt{Expr2: $3, Expr3: $5, Stmt: $7}
- $$.SetPosition($1.Position())
- }
- | FOR stmt_var_or_lets ';' ';' '{' compstmt '}'
- {
- $$ = &ast.CForStmt{Stmt1: $2, Stmt: $6}
- $$.SetPosition($1.Position())
- }
- | FOR stmt_var_or_lets ';' ';' expr '{' compstmt '}'
- {
- $$ = &ast.CForStmt{Stmt1: $2, Expr3: $5, Stmt: $7}
- $$.SetPosition($1.Position())
- }
- | FOR stmt_var_or_lets ';' expr ';' '{' compstmt '}'
- {
- $$ = &ast.CForStmt{Stmt1: $2, Expr2: $4, Stmt: $7}
- $$.SetPosition($1.Position())
- }
- | FOR stmt_var_or_lets ';' expr ';' expr '{' compstmt '}'
- {
- $$ = &ast.CForStmt{Stmt1: $2, Expr2: $4, Expr3: $6, Stmt: $8}
- $$.SetPosition($1.Position())
- }
- stmt_switch :
- SWITCH expr '{' opt_newlines stmt_switch_cases opt_newlines '}'
- {
- switchStmt := $5.(*ast.SwitchStmt)
- switchStmt.Expr = $2
- $$ = switchStmt
- $$.SetPosition($1.Position())
- }
- stmt_switch_cases :
- /* nothing */
- {
- $$ = &ast.SwitchStmt{}
- }
- | stmt_switch_default
- {
- $$ = &ast.SwitchStmt{Default: $1}
- }
- | stmt_switch_case
- {
- $$ = &ast.SwitchStmt{Cases: []ast.Stmt{$1}}
- }
- | stmt_switch_cases stmt_switch_case
- {
- switchStmt := $1.(*ast.SwitchStmt)
- switchStmt.Cases = append(switchStmt.Cases, $2)
- $$ = switchStmt
- }
- | stmt_switch_cases stmt_switch_default
- {
- switchStmt := $1.(*ast.SwitchStmt)
- if switchStmt.Default != nil {
- yylex.Error("multiple default statement")
- }
- switchStmt.Default = $2
- }
- stmt_switch_case :
- CASE expr ':' compstmt
- {
- $$ = &ast.SwitchCaseStmt{Exprs: []ast.Expr{$2}, Stmt: $4}
- $$.SetPosition($1.Position())
- }
- | CASE exprs ':' compstmt
- {
- $$ = &ast.SwitchCaseStmt{Exprs: $2, Stmt: $4}
- $$.SetPosition($1.Position())
- }
- stmt_switch_default :
- DEFAULT ':' compstmt
- {
- $$ = $3
- }
- exprs :
- /* nothing */
- {
- $$ = nil
- }
- | expr
- {
- $$ = []ast.Expr{$1}
- }
- | exprs ',' opt_newlines expr
- {
- if len($1) == 0 {
- yylex.Error("syntax error: unexpected ','")
- }
- $$ = append($1, $4)
- }
- | exprs ',' opt_newlines expr_ident
- {
- if len($1) == 0 {
- yylex.Error("syntax error: unexpected ','")
- }
- $$ = append($1, $4)
- }
- expr :
- expr_member_or_ident
- {
- $$ = $1
- }
- | expr_literals
- {
- $$ = $1
- }
- | expr '?' expr ':' expr
- {
- $$ = &ast.TernaryOpExpr{Expr: $1, LHS: $3, RHS: $5}
- $$.SetPosition($1.Position())
- }
- | expr NILCOALESCE expr
- {
- $$ = &ast.NilCoalescingOpExpr{LHS: $1, RHS: $3}
- $$.SetPosition($1.Position())
- }
- | FUNC '(' expr_idents ')' '{' compstmt '}'
- {
- $$ = &ast.FuncExpr{Params: $3, Stmt: $6}
- $$.SetPosition($1.Position())
- }
- | FUNC '(' expr_idents VARARG ')' '{' compstmt '}'
- {
- $$ = &ast.FuncExpr{Params: $3, Stmt: $7, VarArg: true}
- $$.SetPosition($1.Position())
- }
- | FUNC IDENT '(' expr_idents ')' '{' compstmt '}'
- {
- $$ = &ast.FuncExpr{Name: $2.Lit, Params: $4, Stmt: $7}
- $$.SetPosition($1.Position())
- }
- | FUNC IDENT '(' expr_idents VARARG ')' '{' compstmt '}'
- {
- $$ = &ast.FuncExpr{Name: $2.Lit, Params: $4, Stmt: $8, VarArg: true}
- $$.SetPosition($1.Position())
- }
- | '[' ']'
- {
- $$ = &ast.ArrayExpr{}
- if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) }
- }
- | '[' opt_newlines exprs opt_comma_newlines ']'
- {
- $$ = &ast.ArrayExpr{Exprs: $3}
- if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) }
- }
- | slice_count type_data '{' opt_newlines exprs opt_comma_newlines '}'
- {
- $$ = &ast.ArrayExpr{Exprs: $5, TypeData: &ast.TypeStruct{Kind: ast.TypeSlice, SubType: $2, Dimensions: $1}}
- if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) }
- }
- | '(' expr ')'
- {
- $$ = &ast.ParenExpr{SubExpr: $2}
- if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) }
- }
- | IDENT '(' exprs VARARG ')'
- {
- $$ = &ast.CallExpr{Name: $1.Lit, SubExprs: $3, VarArg: true}
- $$.SetPosition($1.Position())
- }
- | IDENT '(' exprs ')'
- {
- $$ = &ast.CallExpr{Name: $1.Lit, SubExprs: $3}
- $$.SetPosition($1.Position())
- }
- | expr '(' exprs VARARG ')'
- {
- $$ = &ast.AnonCallExpr{Expr: $1, SubExprs: $3, VarArg: true}
- $$.SetPosition($1.Position())
- }
- | expr '(' exprs ')'
- {
- $$ = &ast.AnonCallExpr{Expr: $1, SubExprs: $3}
- $$.SetPosition($1.Position())
- }
- | expr_ident '[' expr ']'
- {
- $$ = &ast.ItemExpr{Item: $1, Index: $3}
- $$.SetPosition($1.Position())
- }
- | expr '[' expr ']'
- {
- $$ = &ast.ItemExpr{Item: $1, Index: $3}
- $$.SetPosition($1.Position())
- }
- | LEN '(' expr ')'
- {
- $$ = &ast.LenExpr{Expr: $3}
- $$.SetPosition($1.Position())
- }
- | IMPORT '(' expr ')'
- {
- $$ = &ast.ImportExpr{Name: $3}
- $$.SetPosition($1.Position())
- }
- | NEW '(' type_data ')'
- {
- if $3.Kind == ast.TypeDefault {
- $3.Kind = ast.TypePtr
- $$ = &ast.MakeExpr{TypeData: $3}
- } else {
- $$ = &ast.MakeExpr{TypeData: &ast.TypeStruct{Kind: ast.TypePtr, SubType: $3}}
- }
- $$.SetPosition($1.Position())
- }
- | MAKE '(' type_data ')'
- {
- $$ = &ast.MakeExpr{TypeData: $3}
- $$.SetPosition($1.Position())
- }
- | MAKE '(' type_data ',' expr ')'
- {
- $$ = &ast.MakeExpr{TypeData: $3, LenExpr: $5}
- $$.SetPosition($1.Position())
- }
- | MAKE '(' type_data ',' expr ',' expr ')'
- {
- $$ = &ast.MakeExpr{TypeData: $3, LenExpr: $5, CapExpr: $7}
- $$.SetPosition($1.Position())
- }
- | MAKE '(' TYPE IDENT ',' expr ')'
- {
- $$ = &ast.MakeTypeExpr{Name: $4.Lit, Type: $6}
- $$.SetPosition($1.Position())
- }
- | expr IN expr
- {
- $$ = &ast.IncludeExpr{ItemExpr: $1, ListExpr: $3}
- $$.SetPosition($1.Position())
- }
- | MAP '{' opt_newlines expr_map opt_comma_newlines '}'
- {
- $4.TypeData = &ast.TypeStruct{Kind: ast.TypeMap, Key: &ast.TypeStruct{Name: "interface"}, SubType: &ast.TypeStruct{Name: "interface"}}
- $$ = $4
- $$.SetPosition($1.Position())
- }
- | MAP '[' type_data ']' type_data '{' opt_newlines expr_map opt_comma_newlines '}'
- {
- $8.TypeData = &ast.TypeStruct{Kind: ast.TypeMap, Key: $3, SubType: $5}
- $$ = $8
- $$.SetPosition($1.Position())
- }
- | '{' opt_newlines expr_map opt_comma_newlines '}'
- {
- $$ = $3
- $$.SetPosition($3.Position())
- }
- | expr_slice
- {
- $$ = $1
- $$.SetPosition($1.Position())
- }
- | expr_chan
- {
- $$ = $1
- $$.SetPosition($1.Position())
- }
- | expr_unary
- | expr_binary
- | expr_lets
- expr_idents :
- {
- $$ = []string{}
- }
- | IDENT
- {
- $$ = []string{$1.Lit}
- }
- | expr_idents ',' opt_newlines IDENT
- {
- if len($1) == 0 {
- yylex.Error("syntax error: unexpected ','")
- }
- $$ = append($1, $4.Lit)
- }
- type_data :
- IDENT
- {
- $$ = &ast.TypeStruct{Name: $1.Lit}
- }
- | type_data '.' IDENT
- {
- if $1.Kind != ast.TypeDefault {
- yylex.Error("not type default")
- } else {
- $1.Env = append($1.Env, $1.Name)
- $1.Name = $3.Lit
- }
- }
- | '*' type_data
- {
- if $2.Kind == ast.TypeDefault {
- $2.Kind = ast.TypePtr
- $$ = $2
- } else {
- $$ = &ast.TypeStruct{Kind: ast.TypePtr, SubType: $2}
- }
- }
- | slice_count type_data
- {
- if $2.Kind == ast.TypeDefault {
- $2.Kind = ast.TypeSlice
- $2.Dimensions = $1
- $$ = $2
- } else {
- $$ = &ast.TypeStruct{Kind: ast.TypeSlice, SubType: $2, Dimensions: $1}
- }
- }
- | MAP '[' type_data ']' type_data
- {
- $$ = &ast.TypeStruct{Kind: ast.TypeMap, Key: $3, SubType: $5}
- }
- | CHAN type_data
- {
- if $2.Kind == ast.TypeDefault {
- $2.Kind = ast.TypeChan
- $$ = $2
- } else {
- $$ = &ast.TypeStruct{Kind: ast.TypeChan, SubType: $2}
- }
- }
- | STRUCT '{' opt_newlines type_data_struct opt_newlines '}'
- {
- $$ = $4
- }
- type_data_struct :
- IDENT type_data
- {
- $$ = &ast.TypeStruct{Kind: ast.TypeStructType, StructNames: []string{$1.Lit}, StructTypes: []*ast.TypeStruct{$2}}
- }
- | type_data_struct ',' opt_newlines IDENT type_data
- {
- if $1 == nil {
- yylex.Error("syntax error: unexpected ','")
- }
- $$.StructNames = append($$.StructNames, $4.Lit)
- $$.StructTypes = append($$.StructTypes, $5)
- }
- slice_count :
- '[' ']'
- {
- $$ = 1
- }
- | '[' ']' slice_count
- {
- $$ = $3 + 1
- }
- expr_member_or_ident :
- expr_member
- {
- $$ = $1
- }
- | expr_ident
- {
- $$ = $1
- }
- expr_member :
- expr '.' IDENT
- {
- $$ = &ast.MemberExpr{Expr: $1, Name: $3.Lit}
- $$.SetPosition($1.Position())
- }
- expr_ident :
- IDENT
- {
- $$ = &ast.IdentExpr{Lit: $1.Lit}
- $$.SetPosition($1.Position())
- }
- expr_literals :
- '-' NUMBER
- {
- num, err := toNumber("-" + $2.Lit)
- if err != nil {
- yylex.Error("invalid number: -" + $2.Lit)
- }
- $$ = &ast.LiteralExpr{Literal: num}
- $$.SetPosition($2.Position())
- }
- | NUMBER
- {
- num, err := toNumber($1.Lit)
- if err != nil {
- yylex.Error("invalid number: " + $1.Lit)
- }
- $$ = &ast.LiteralExpr{Literal: num}
- $$.SetPosition($1.Position())
- }
- | STRING
- {
- $$ = &ast.LiteralExpr{Literal: stringToValue($1.Lit)}
- $$.SetPosition($1.Position())
- }
- | TRUE
- {
- $$ = &ast.LiteralExpr{Literal: trueValue}
- $$.SetPosition($1.Position())
- }
- | FALSE
- {
- $$ = &ast.LiteralExpr{Literal: falseValue}
- $$.SetPosition($1.Position())
- }
- | NIL
- {
- $$ = &ast.LiteralExpr{Literal: nilValue}
- $$.SetPosition($1.Position())
- }
- expr_map :
- /* nothing */
- {
- $$ = &ast.MapExpr{}
- }
- | expr ':' expr
- {
- $$ = &ast.MapExpr{Keys: []ast.Expr{$1}, Values: []ast.Expr{$3}}
- }
- | expr_map ',' opt_newlines expr ':' expr
- {
- if $1.Keys == nil {
- yylex.Error("syntax error: unexpected ','")
- }
- $$.Keys = append($$.Keys, $4)
- $$.Values = append($$.Values, $6)
- }
- expr_slice :
- expr_ident '[' expr ':' expr ']'
- {
- $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: $5}
- }
- | expr_ident '[' expr ':' ']'
- {
- $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: nil}
- }
- | expr_ident '[' ':' expr ']'
- {
- $$ = &ast.SliceExpr{Item: $1, Begin: nil, End: $4}
- }
- | expr_ident '[' ':' expr ':' expr ']'
- {
- $$ = &ast.SliceExpr{Item: $1, End: $4, Cap: $6}
- }
- | expr_ident '[' expr ':' expr ':' expr ']'
- {
- $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: $5, Cap: $7}
- }
- | expr '[' expr ':' expr ']'
- {
- $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: $5}
- }
- | expr '[' expr ':' ']'
- {
- $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: nil}
- }
- | expr '[' ':' expr ']'
- {
- $$ = &ast.SliceExpr{Item: $1, Begin: nil, End: $4}
- }
- | expr '[' ':' expr ':' expr ']'
- {
- $$ = &ast.SliceExpr{Item: $1, End: $4, Cap: $6}
- }
- | expr '[' expr ':' expr ':' expr ']'
- {
- $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: $5, Cap: $7}
- }
- expr_chan :
- expr OPCHAN expr
- {
- $$ = &ast.ChanExpr{LHS: $1, RHS: $3}
- }
- | OPCHAN expr
- {
- $$ = &ast.ChanExpr{RHS: $2}
- }
- expr_unary :
- '-' expr %prec UNARY
- {
- $$ = &ast.UnaryExpr{Operator: "-", Expr: $2}
- $$.SetPosition($2.Position())
- }
- | '!' expr %prec UNARY
- {
- $$ = &ast.UnaryExpr{Operator: "!", Expr: $2}
- $$.SetPosition($2.Position())
- }
- | '^' expr %prec UNARY
- {
- $$ = &ast.UnaryExpr{Operator: "^", Expr: $2}
- $$.SetPosition($2.Position())
- }
- | '&' expr %prec UNARY
- {
- $$ = &ast.AddrExpr{Expr: $2}
- $$.SetPosition($2.Position())
- }
- | '*' expr %prec UNARY
- {
- $$ = &ast.DerefExpr{Expr: $2}
- $$.SetPosition($2.Position())
- }
- expr_binary :
- op_multiply
- {
- $$ = &ast.OpExpr{Op: $1}
- $$.SetPosition($1.Position())
- }
- | op_add
- {
- $$ = &ast.OpExpr{Op: $1}
- $$.SetPosition($1.Position())
- }
- | op_comparison
- {
- $$ = &ast.OpExpr{Op: $1}
- $$.SetPosition($1.Position())
- }
- | op_binary
- {
- $$ = &ast.OpExpr{Op: $1}
- $$.SetPosition($1.Position())
- }
- expr_lets:
- expr PLUSPLUS
- {
- rhs := &ast.OpExpr{Op: &ast.AddOperator{LHS: $1, Operator: "+", RHS: oneLiteral}}
- rhs.Op.SetPosition($1.Position())
- rhs.SetPosition($1.Position())
- $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
- $$.SetPosition($1.Position())
- }
- | expr MINUSMINUS
- {
- rhs := &ast.OpExpr{Op: &ast.AddOperator{LHS: $1, Operator: "-", RHS: oneLiteral}}
- rhs.Op.SetPosition($1.Position())
- rhs.SetPosition($1.Position())
- $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
- $$.SetPosition($1.Position())
- }
- | expr PLUSEQ expr
- {
- rhs := &ast.OpExpr{Op: &ast.AddOperator{LHS: $1, Operator: "+", RHS: $3}}
- rhs.Op.SetPosition($1.Position())
- rhs.SetPosition($1.Position())
- $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
- $$.SetPosition($1.Position())
- }
- | expr MINUSEQ expr
- {
- rhs := &ast.OpExpr{Op: &ast.AddOperator{LHS: $1, Operator: "-", RHS: $3}}
- rhs.Op.SetPosition($1.Position())
- rhs.SetPosition($1.Position())
- $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
- $$.SetPosition($1.Position())
- }
- | expr OREQ expr
- {
- rhs := &ast.OpExpr{Op: &ast.AddOperator{LHS: $1, Operator: "|", RHS: $3}}
- rhs.Op.SetPosition($1.Position())
- rhs.SetPosition($1.Position())
- $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
- $$.SetPosition($1.Position())
- }
- | expr MULEQ expr
- {
- rhs := &ast.OpExpr{Op: &ast.MultiplyOperator{LHS: $1, Operator: "*", RHS: $3}}
- rhs.Op.SetPosition($1.Position())
- rhs.SetPosition($1.Position())
- $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
- $$.SetPosition($1.Position())
- }
- | expr DIVEQ expr
- {
- rhs := &ast.OpExpr{Op: &ast.MultiplyOperator{LHS: $1, Operator: "/", RHS: $3}}
- rhs.Op.SetPosition($1.Position())
- rhs.SetPosition($1.Position())
- $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
- $$.SetPosition($1.Position())
- }
- | expr ANDEQ expr
- {
- rhs := &ast.OpExpr{Op: &ast.MultiplyOperator{LHS: $1, Operator: "&", RHS: $3}}
- rhs.Op.SetPosition($1.Position())
- rhs.SetPosition($1.Position())
- $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}}
- $$.SetPosition($1.Position())
- }
- op_multiply :
- expr '*' expr
- {
- $$ = &ast.MultiplyOperator{LHS: $1, Operator: "*", RHS: $3}
- $$.SetPosition($1.Position())
- }
- | expr '/' expr
- {
- $$ = &ast.MultiplyOperator{LHS: $1, Operator: "/", RHS: $3}
- $$.SetPosition($1.Position())
- }
- | expr '%' expr
- {
- $$ = &ast.MultiplyOperator{LHS: $1, Operator: "%", RHS: $3}
- $$.SetPosition($1.Position())
- }
- | expr SHIFTLEFT expr
- {
- $$ = &ast.MultiplyOperator{LHS: $1, Operator: "<<", RHS: $3}
- $$.SetPosition($1.Position())
- }
- | expr SHIFTRIGHT expr
- {
- $$ = &ast.MultiplyOperator{LHS: $1, Operator: ">>", RHS: $3}
- $$.SetPosition($1.Position())
- }
- | expr '&' expr
- {
- $$ = &ast.MultiplyOperator{LHS: $1, Operator: "&", RHS: $3}
- $$.SetPosition($1.Position())
- }
- op_add :
- expr '+' expr
- {
- $$ = &ast.AddOperator{LHS: $1, Operator: "+", RHS: $3}
- $$.SetPosition($1.Position())
- }
- | expr '-' expr
- {
- $$ = &ast.AddOperator{LHS: $1, Operator: "-", RHS: $3}
- $$.SetPosition($1.Position())
- }
- | expr '|' expr
- {
- $$ = &ast.AddOperator{LHS: $1, Operator: "|", RHS: $3}
- $$.SetPosition($1.Position())
- }
- op_comparison :
- expr EQEQ expr
- {
- $$ = &ast.ComparisonOperator{LHS: $1, Operator: "==", RHS: $3}
- $$.SetPosition($1.Position())
- }
- | expr NEQ expr
- {
- $$ = &ast.ComparisonOperator{LHS: $1, Operator: "!=", RHS: $3}
- $$.SetPosition($1.Position())
- }
- | expr '<' expr
- {
- $$ = &ast.ComparisonOperator{LHS: $1, Operator: "<", RHS: $3}
- $$.SetPosition($1.Position())
- }
- | expr LE expr
- {
- $$ = &ast.ComparisonOperator{LHS: $1, Operator: "<=", RHS: $3}
- $$.SetPosition($1.Position())
- }
- | expr '>' expr
- {
- $$ = &ast.ComparisonOperator{LHS: $1, Operator: ">", RHS: $3}
- $$.SetPosition($1.Position())
- }
- | expr GE expr
- {
- $$ = &ast.ComparisonOperator{LHS: $1, Operator: ">=", RHS: $3}
- $$.SetPosition($1.Position())
- }
- op_binary :
- expr ANDAND expr
- {
- $$ = &ast.BinaryOperator{LHS: $1, Operator: "&&", RHS: $3}
- $$.SetPosition($1.Position())
- }
- | expr OROR expr
- {
- $$ = &ast.BinaryOperator{LHS: $1, Operator: "||", RHS: $3}
- $$.SetPosition($1.Position())
- }
- opt_term :
- /* nothing */
- | term
-
- term :
- ';' newlines
- | newlines
- | ';'
- opt_newlines :
- /* nothing */
- | newlines
- newlines :
- newline
- | newlines newline
- newline : '\n'
- opt_comma_newlines :
- /* nothing */
- | ',' newlines
- | newlines
- | ','
- %%
|