github.com/mattn/anko@v0.1.10/parser/parser.go.y (about) 1 %{ 2 package parser 3 4 import ( 5 "github.com/mattn/anko/ast" 6 ) 7 8 %} 9 10 %type<compstmt> compstmt 11 %type<stmts> stmts 12 %type<stmt> stmt 13 %type<stmt_var_or_lets> stmt_var_or_lets 14 %type<stmt_var> stmt_var 15 %type<stmt_lets> stmt_lets 16 %type<stmt_if> stmt_if 17 %type<stmt_for> stmt_for 18 %type<stmt_switch> stmt_switch 19 %type<stmt_switch_cases> stmt_switch_cases 20 %type<stmt_switch_case> stmt_switch_case 21 %type<stmt_switch_default> stmt_switch_default 22 23 %type<exprs> exprs 24 %type<expr> expr 25 %type<expr_idents> expr_idents 26 %type<type_data> type_data 27 %type<type_data_struct> type_data_struct 28 %type<slice_count> slice_count 29 %type<expr_member_or_ident> expr_member_or_ident 30 %type<expr_member> expr_member 31 %type<expr_ident> expr_ident 32 %type<expr_literals> expr_literals 33 %type<expr_map> expr_map 34 %type<expr_slice> expr_slice 35 %type<expr_chan> expr_chan 36 %type<expr> expr_unary 37 %type<expr> expr_binary 38 %type<expr> expr_lets 39 40 %type<expr> op_binary 41 %type<expr> op_comparison 42 %type<expr> op_add 43 %type<expr> op_multiply 44 45 %union{ 46 tok ast.Token 47 48 compstmt ast.Stmt 49 stmts ast.Stmt 50 stmt ast.Stmt 51 stmt_var_or_lets ast.Stmt 52 stmt_var ast.Stmt 53 stmt_lets ast.Stmt 54 stmt_if ast.Stmt 55 stmt_for ast.Stmt 56 stmt_switch ast.Stmt 57 stmt_switch_cases ast.Stmt 58 stmt_switch_case ast.Stmt 59 stmt_switch_default ast.Stmt 60 61 exprs []ast.Expr 62 expr ast.Expr 63 expr_idents []string 64 type_data *ast.TypeStruct 65 type_data_struct *ast.TypeStruct 66 slice_count int 67 expr_member_or_ident ast.Expr 68 expr_member *ast.MemberExpr 69 expr_ident *ast.IdentExpr 70 expr_literals ast.Expr 71 expr_map *ast.MapExpr 72 expr_slice ast.Expr 73 expr_chan ast.Expr 74 expr_unary ast.Expr 75 expr_binary ast.Expr 76 expr_lets ast.Expr 77 78 op_binary ast.Operator 79 op_comparison ast.Operator 80 op_add ast.Operator 81 op_multiply ast.Operator 82 } 83 84 %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 85 86 /* lowest precedence */ 87 %left , 88 %right '=' PLUSEQ MINUSEQ MULEQ DIVEQ ANDEQ OREQ EQOPCHAN 89 %right ':' 90 %right OPCHAN 91 %right '?' NILCOALESCE 92 %left OROR 93 %left ANDAND 94 %left EQEQ NEQ '<' LE '>' GE 95 %left '+' '-' '|' '^' 96 %left '*' '/' '%' SHIFTLEFT SHIFTRIGHT '&' 97 %right IN 98 %right PLUSPLUS MINUSMINUS 99 %right UNARY 100 /* highest precedence */ 101 /* https://golang.org/ref/spec#Expression */ 102 103 104 %% 105 106 compstmt : 107 opt_term 108 { 109 $$ = nil 110 } 111 | stmts opt_term 112 { 113 $$ = $1 114 } 115 116 stmts : 117 opt_term stmt 118 { 119 if $2 != nil { 120 $$ = &ast.StmtsStmt{Stmts: []ast.Stmt{$2}} 121 } 122 if l, ok := yylex.(*Lexer); ok { 123 l.stmt = $$ 124 } 125 } 126 | stmts term stmt 127 { 128 if $3 != nil { 129 if $1 == nil { 130 $$ = &ast.StmtsStmt{Stmts: []ast.Stmt{$3}} 131 } else { 132 stmts := $1.(*ast.StmtsStmt) 133 stmts.Stmts = append(stmts.Stmts, $3) 134 } 135 if l, ok := yylex.(*Lexer); ok { 136 l.stmt = $$ 137 } 138 } 139 } 140 141 stmt : 142 /* nothing */ 143 { 144 $$ = nil 145 } 146 | stmt_var_or_lets 147 { 148 $$ = $1 149 } 150 | BREAK 151 { 152 $$ = &ast.BreakStmt{} 153 $$.SetPosition($1.Position()) 154 } 155 | CONTINUE 156 { 157 $$ = &ast.ContinueStmt{} 158 $$.SetPosition($1.Position()) 159 } 160 | RETURN exprs 161 { 162 $$ = &ast.ReturnStmt{Exprs: $2} 163 $$.SetPosition($1.Position()) 164 } 165 | THROW expr 166 { 167 $$ = &ast.ThrowStmt{Expr: $2} 168 $$.SetPosition($1.Position()) 169 } 170 | MODULE IDENT '{' compstmt '}' 171 { 172 $$ = &ast.ModuleStmt{Name: $2.Lit, Stmt: $4} 173 $$.SetPosition($1.Position()) 174 } 175 | TRY '{' compstmt '}' CATCH IDENT '{' compstmt '}' FINALLY '{' compstmt '}' 176 { 177 $$ = &ast.TryStmt{Try: $3, Var: $6.Lit, Catch: $8, Finally: $12} 178 $$.SetPosition($1.Position()) 179 } 180 | TRY '{' compstmt '}' CATCH '{' compstmt '}' FINALLY '{' compstmt '}' 181 { 182 $$ = &ast.TryStmt{Try: $3, Catch: $7, Finally: $11} 183 $$.SetPosition($1.Position()) 184 } 185 | TRY '{' compstmt '}' CATCH IDENT '{' compstmt '}' 186 { 187 $$ = &ast.TryStmt{Try: $3, Var: $6.Lit, Catch: $8} 188 $$.SetPosition($1.Position()) 189 } 190 | TRY '{' compstmt '}' CATCH '{' compstmt '}' 191 { 192 $$ = &ast.TryStmt{Try: $3, Catch: $7} 193 $$.SetPosition($1.Position()) 194 } 195 | GO IDENT '(' exprs VARARG ')' 196 { 197 $$ = &ast.GoroutineStmt{Expr: &ast.CallExpr{Name: $2.Lit, SubExprs: $4, VarArg: true, Go: true}} 198 $$.SetPosition($2.Position()) 199 } 200 | GO IDENT '(' exprs ')' 201 { 202 $$ = &ast.GoroutineStmt{Expr: &ast.CallExpr{Name: $2.Lit, SubExprs: $4, Go: true}} 203 $$.SetPosition($2.Position()) 204 } 205 | GO expr '(' exprs VARARG ')' 206 { 207 $$ = &ast.GoroutineStmt{Expr: &ast.AnonCallExpr{Expr: $2, SubExprs: $4, VarArg: true, Go: true}} 208 $$.SetPosition($2.Position()) 209 } 210 | GO expr '(' exprs ')' 211 { 212 $$ = &ast.GoroutineStmt{Expr: &ast.AnonCallExpr{Expr: $2, SubExprs: $4, Go: true}} 213 $$.SetPosition($1.Position()) 214 } 215 | DELETE '(' expr ')' 216 { 217 $$ = &ast.DeleteStmt{Item: $3} 218 $$.SetPosition($1.Position()) 219 } 220 | DELETE '(' expr ',' expr ')' 221 { 222 $$ = &ast.DeleteStmt{Item: $3, Key: $5} 223 $$.SetPosition($1.Position()) 224 } 225 | CLOSE '(' expr ')' 226 { 227 $$ = &ast.CloseStmt{Expr: $3} 228 $$.SetPosition($1.Position()) 229 } 230 | stmt_if 231 { 232 $$ = $1 233 } 234 | stmt_for 235 { 236 $$ = $1 237 } 238 | stmt_switch 239 { 240 $$ = $1 241 } 242 | expr 243 { 244 $$ = &ast.ExprStmt{Expr: $1} 245 $$.SetPosition($1.Position()) 246 } 247 248 stmt_var_or_lets : 249 stmt_var 250 { 251 $$ = $1 252 } 253 | stmt_lets 254 { 255 $$ = $1 256 } 257 258 stmt_var : 259 VAR expr_idents '=' exprs 260 { 261 $$ = &ast.VarStmt{Names: $2, Exprs: $4} 262 $$.SetPosition($1.Position()) 263 } 264 265 stmt_lets : 266 expr '=' expr 267 { 268 $$ = &ast.LetsStmt{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{$3}} 269 $$.SetPosition($1.Position()) 270 } 271 | exprs '=' exprs 272 { 273 if len($1) == 2 && len($3) == 1 { 274 if _, ok := $3[0].(*ast.ItemExpr); ok { 275 $$ = &ast.LetMapItemStmt{LHSS: $1, RHS: $3[0]} 276 } else { 277 $$ = &ast.LetsStmt{LHSS: $1, RHSS: $3} 278 } 279 } else { 280 $$ = &ast.LetsStmt{LHSS: $1, RHSS: $3} 281 } 282 $$.SetPosition($1[0].Position()) 283 } 284 | expr EQOPCHAN expr 285 { 286 $$ = &ast.ChanStmt{LHS: $1, RHS: $3} 287 $$.SetPosition($1.Position()) 288 } 289 | exprs EQOPCHAN expr 290 { 291 if len($1) == 2 { 292 chanStmt := &ast.ChanStmt{LHS: $1[0].(ast.Expr), OkExpr: $1[1].(ast.Expr), RHS: $3} 293 $$ = chanStmt 294 $$.SetPosition(chanStmt.LHS.Position()) 295 } else if len($1) < 2 { 296 yylex.Error("missing expressions on left side of channel operator") 297 $$ = &ast.ChanStmt{RHS: $3} 298 $$.SetPosition($2.Position()) 299 } 300 } 301 302 stmt_if : 303 IF expr '{' compstmt '}' 304 { 305 $$ = &ast.IfStmt{If: $2, Then: $4, Else: nil} 306 $$.SetPosition($1.Position()) 307 } 308 | stmt_if ELSE IF expr '{' compstmt '}' 309 { 310 ifStmt := $1.(*ast.IfStmt) 311 ifStmt.ElseIf = append(ifStmt.ElseIf, &ast.IfStmt{If: $4, Then: $6}) 312 } 313 | stmt_if ELSE '{' compstmt '}' 314 { 315 ifStmt := $1.(*ast.IfStmt) 316 if ifStmt.Else != nil { 317 yylex.Error("multiple else statement") 318 } 319 ifStmt.Else = $4 320 } 321 322 stmt_for : 323 FOR '{' compstmt '}' 324 { 325 $$ = &ast.LoopStmt{Stmt: $3} 326 $$.SetPosition($1.Position()) 327 } 328 | FOR expr_idents IN expr '{' compstmt '}' 329 { 330 if len($2) < 1 { 331 yylex.Error("missing identifier") 332 } else if len($2) > 2 { 333 yylex.Error("too many identifiers") 334 } else { 335 $$ = &ast.ForStmt{Vars: $2, Value: $4, Stmt: $6} 336 $$.SetPosition($1.Position()) 337 } 338 } 339 | FOR expr '{' compstmt '}' 340 { 341 $$ = &ast.LoopStmt{Expr: $2, Stmt: $4} 342 $$.SetPosition($1.Position()) 343 } 344 | FOR ';' ';' '{' compstmt '}' 345 { 346 $$ = &ast.CForStmt{Stmt: $5} 347 $$.SetPosition($1.Position()) 348 } 349 | FOR ';' ';' expr '{' compstmt '}' 350 { 351 $$ = &ast.CForStmt{Expr3: $4, Stmt: $6} 352 $$.SetPosition($1.Position()) 353 } 354 | FOR ';' expr ';' '{' compstmt '}' 355 { 356 $$ = &ast.CForStmt{Expr2: $3, Stmt: $6} 357 $$.SetPosition($1.Position()) 358 } 359 | FOR ';' expr ';' expr '{' compstmt '}' 360 { 361 $$ = &ast.CForStmt{Expr2: $3, Expr3: $5, Stmt: $7} 362 $$.SetPosition($1.Position()) 363 } 364 | FOR stmt_var_or_lets ';' ';' '{' compstmt '}' 365 { 366 $$ = &ast.CForStmt{Stmt1: $2, Stmt: $6} 367 $$.SetPosition($1.Position()) 368 } 369 | FOR stmt_var_or_lets ';' ';' expr '{' compstmt '}' 370 { 371 $$ = &ast.CForStmt{Stmt1: $2, Expr3: $5, Stmt: $7} 372 $$.SetPosition($1.Position()) 373 } 374 | FOR stmt_var_or_lets ';' expr ';' '{' compstmt '}' 375 { 376 $$ = &ast.CForStmt{Stmt1: $2, Expr2: $4, Stmt: $7} 377 $$.SetPosition($1.Position()) 378 } 379 | FOR stmt_var_or_lets ';' expr ';' expr '{' compstmt '}' 380 { 381 $$ = &ast.CForStmt{Stmt1: $2, Expr2: $4, Expr3: $6, Stmt: $8} 382 $$.SetPosition($1.Position()) 383 } 384 385 stmt_switch : 386 SWITCH expr '{' opt_newlines stmt_switch_cases opt_newlines '}' 387 { 388 switchStmt := $5.(*ast.SwitchStmt) 389 switchStmt.Expr = $2 390 $$ = switchStmt 391 $$.SetPosition($1.Position()) 392 } 393 394 stmt_switch_cases : 395 /* nothing */ 396 { 397 $$ = &ast.SwitchStmt{} 398 } 399 | stmt_switch_default 400 { 401 $$ = &ast.SwitchStmt{Default: $1} 402 } 403 | stmt_switch_case 404 { 405 $$ = &ast.SwitchStmt{Cases: []ast.Stmt{$1}} 406 } 407 | stmt_switch_cases stmt_switch_case 408 { 409 switchStmt := $1.(*ast.SwitchStmt) 410 switchStmt.Cases = append(switchStmt.Cases, $2) 411 $$ = switchStmt 412 } 413 | stmt_switch_cases stmt_switch_default 414 { 415 switchStmt := $1.(*ast.SwitchStmt) 416 if switchStmt.Default != nil { 417 yylex.Error("multiple default statement") 418 } 419 switchStmt.Default = $2 420 } 421 422 stmt_switch_case : 423 CASE expr ':' compstmt 424 { 425 $$ = &ast.SwitchCaseStmt{Exprs: []ast.Expr{$2}, Stmt: $4} 426 $$.SetPosition($1.Position()) 427 } 428 | CASE exprs ':' compstmt 429 { 430 $$ = &ast.SwitchCaseStmt{Exprs: $2, Stmt: $4} 431 $$.SetPosition($1.Position()) 432 } 433 434 stmt_switch_default : 435 DEFAULT ':' compstmt 436 { 437 $$ = $3 438 } 439 440 441 exprs : 442 /* nothing */ 443 { 444 $$ = nil 445 } 446 | expr 447 { 448 $$ = []ast.Expr{$1} 449 } 450 | exprs ',' opt_newlines expr 451 { 452 if len($1) == 0 { 453 yylex.Error("syntax error: unexpected ','") 454 } 455 $$ = append($1, $4) 456 } 457 | exprs ',' opt_newlines expr_ident 458 { 459 if len($1) == 0 { 460 yylex.Error("syntax error: unexpected ','") 461 } 462 $$ = append($1, $4) 463 } 464 465 expr : 466 expr_member_or_ident 467 { 468 $$ = $1 469 } 470 | expr_literals 471 { 472 $$ = $1 473 } 474 | expr '?' expr ':' expr 475 { 476 $$ = &ast.TernaryOpExpr{Expr: $1, LHS: $3, RHS: $5} 477 $$.SetPosition($1.Position()) 478 } 479 | expr NILCOALESCE expr 480 { 481 $$ = &ast.NilCoalescingOpExpr{LHS: $1, RHS: $3} 482 $$.SetPosition($1.Position()) 483 } 484 | FUNC '(' expr_idents ')' '{' compstmt '}' 485 { 486 $$ = &ast.FuncExpr{Params: $3, Stmt: $6} 487 $$.SetPosition($1.Position()) 488 } 489 | FUNC '(' expr_idents VARARG ')' '{' compstmt '}' 490 { 491 $$ = &ast.FuncExpr{Params: $3, Stmt: $7, VarArg: true} 492 $$.SetPosition($1.Position()) 493 } 494 | FUNC IDENT '(' expr_idents ')' '{' compstmt '}' 495 { 496 $$ = &ast.FuncExpr{Name: $2.Lit, Params: $4, Stmt: $7} 497 $$.SetPosition($1.Position()) 498 } 499 | FUNC IDENT '(' expr_idents VARARG ')' '{' compstmt '}' 500 { 501 $$ = &ast.FuncExpr{Name: $2.Lit, Params: $4, Stmt: $8, VarArg: true} 502 $$.SetPosition($1.Position()) 503 } 504 | '[' ']' 505 { 506 $$ = &ast.ArrayExpr{} 507 if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) } 508 } 509 | '[' opt_newlines exprs opt_comma_newlines ']' 510 { 511 $$ = &ast.ArrayExpr{Exprs: $3} 512 if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) } 513 } 514 | slice_count type_data '{' opt_newlines exprs opt_comma_newlines '}' 515 { 516 $$ = &ast.ArrayExpr{Exprs: $5, TypeData: &ast.TypeStruct{Kind: ast.TypeSlice, SubType: $2, Dimensions: $1}} 517 if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) } 518 } 519 | '(' expr ')' 520 { 521 $$ = &ast.ParenExpr{SubExpr: $2} 522 if l, ok := yylex.(*Lexer); ok { $$.SetPosition(l.pos) } 523 } 524 | IDENT '(' exprs VARARG ')' 525 { 526 $$ = &ast.CallExpr{Name: $1.Lit, SubExprs: $3, VarArg: true} 527 $$.SetPosition($1.Position()) 528 } 529 | IDENT '(' exprs ')' 530 { 531 $$ = &ast.CallExpr{Name: $1.Lit, SubExprs: $3} 532 $$.SetPosition($1.Position()) 533 } 534 | expr '(' exprs VARARG ')' 535 { 536 $$ = &ast.AnonCallExpr{Expr: $1, SubExprs: $3, VarArg: true} 537 $$.SetPosition($1.Position()) 538 } 539 | expr '(' exprs ')' 540 { 541 $$ = &ast.AnonCallExpr{Expr: $1, SubExprs: $3} 542 $$.SetPosition($1.Position()) 543 } 544 | expr_ident '[' expr ']' 545 { 546 $$ = &ast.ItemExpr{Item: $1, Index: $3} 547 $$.SetPosition($1.Position()) 548 } 549 | expr '[' expr ']' 550 { 551 $$ = &ast.ItemExpr{Item: $1, Index: $3} 552 $$.SetPosition($1.Position()) 553 } 554 | LEN '(' expr ')' 555 { 556 $$ = &ast.LenExpr{Expr: $3} 557 $$.SetPosition($1.Position()) 558 } 559 | IMPORT '(' expr ')' 560 { 561 $$ = &ast.ImportExpr{Name: $3} 562 $$.SetPosition($1.Position()) 563 } 564 | NEW '(' type_data ')' 565 { 566 if $3.Kind == ast.TypeDefault { 567 $3.Kind = ast.TypePtr 568 $$ = &ast.MakeExpr{TypeData: $3} 569 } else { 570 $$ = &ast.MakeExpr{TypeData: &ast.TypeStruct{Kind: ast.TypePtr, SubType: $3}} 571 } 572 $$.SetPosition($1.Position()) 573 } 574 | MAKE '(' type_data ')' 575 { 576 $$ = &ast.MakeExpr{TypeData: $3} 577 $$.SetPosition($1.Position()) 578 } 579 | MAKE '(' type_data ',' expr ')' 580 { 581 $$ = &ast.MakeExpr{TypeData: $3, LenExpr: $5} 582 $$.SetPosition($1.Position()) 583 } 584 | MAKE '(' type_data ',' expr ',' expr ')' 585 { 586 $$ = &ast.MakeExpr{TypeData: $3, LenExpr: $5, CapExpr: $7} 587 $$.SetPosition($1.Position()) 588 } 589 | MAKE '(' TYPE IDENT ',' expr ')' 590 { 591 $$ = &ast.MakeTypeExpr{Name: $4.Lit, Type: $6} 592 $$.SetPosition($1.Position()) 593 } 594 | expr IN expr 595 { 596 $$ = &ast.IncludeExpr{ItemExpr: $1, ListExpr: $3} 597 $$.SetPosition($1.Position()) 598 } 599 | MAP '{' opt_newlines expr_map opt_comma_newlines '}' 600 { 601 $4.TypeData = &ast.TypeStruct{Kind: ast.TypeMap, Key: &ast.TypeStruct{Name: "interface"}, SubType: &ast.TypeStruct{Name: "interface"}} 602 $$ = $4 603 $$.SetPosition($1.Position()) 604 } 605 | MAP '[' type_data ']' type_data '{' opt_newlines expr_map opt_comma_newlines '}' 606 { 607 $8.TypeData = &ast.TypeStruct{Kind: ast.TypeMap, Key: $3, SubType: $5} 608 $$ = $8 609 $$.SetPosition($1.Position()) 610 } 611 | '{' opt_newlines expr_map opt_comma_newlines '}' 612 { 613 $$ = $3 614 $$.SetPosition($3.Position()) 615 } 616 | expr_slice 617 { 618 $$ = $1 619 $$.SetPosition($1.Position()) 620 } 621 | expr_chan 622 { 623 $$ = $1 624 $$.SetPosition($1.Position()) 625 } 626 | expr_unary 627 | expr_binary 628 | expr_lets 629 630 expr_idents : 631 { 632 $$ = []string{} 633 } 634 | IDENT 635 { 636 $$ = []string{$1.Lit} 637 } 638 | expr_idents ',' opt_newlines IDENT 639 { 640 if len($1) == 0 { 641 yylex.Error("syntax error: unexpected ','") 642 } 643 $$ = append($1, $4.Lit) 644 } 645 646 type_data : 647 IDENT 648 { 649 $$ = &ast.TypeStruct{Name: $1.Lit} 650 } 651 | type_data '.' IDENT 652 { 653 if $1.Kind != ast.TypeDefault { 654 yylex.Error("not type default") 655 } else { 656 $1.Env = append($1.Env, $1.Name) 657 $1.Name = $3.Lit 658 } 659 } 660 | '*' type_data 661 { 662 if $2.Kind == ast.TypeDefault { 663 $2.Kind = ast.TypePtr 664 $$ = $2 665 } else { 666 $$ = &ast.TypeStruct{Kind: ast.TypePtr, SubType: $2} 667 } 668 } 669 | slice_count type_data 670 { 671 if $2.Kind == ast.TypeDefault { 672 $2.Kind = ast.TypeSlice 673 $2.Dimensions = $1 674 $$ = $2 675 } else { 676 $$ = &ast.TypeStruct{Kind: ast.TypeSlice, SubType: $2, Dimensions: $1} 677 } 678 } 679 | MAP '[' type_data ']' type_data 680 { 681 $$ = &ast.TypeStruct{Kind: ast.TypeMap, Key: $3, SubType: $5} 682 } 683 | CHAN type_data 684 { 685 if $2.Kind == ast.TypeDefault { 686 $2.Kind = ast.TypeChan 687 $$ = $2 688 } else { 689 $$ = &ast.TypeStruct{Kind: ast.TypeChan, SubType: $2} 690 } 691 } 692 | STRUCT '{' opt_newlines type_data_struct opt_newlines '}' 693 { 694 $$ = $4 695 } 696 697 type_data_struct : 698 IDENT type_data 699 { 700 $$ = &ast.TypeStruct{Kind: ast.TypeStructType, StructNames: []string{$1.Lit}, StructTypes: []*ast.TypeStruct{$2}} 701 } 702 | type_data_struct ',' opt_newlines IDENT type_data 703 { 704 if $1 == nil { 705 yylex.Error("syntax error: unexpected ','") 706 } 707 $$.StructNames = append($$.StructNames, $4.Lit) 708 $$.StructTypes = append($$.StructTypes, $5) 709 } 710 711 slice_count : 712 '[' ']' 713 { 714 $$ = 1 715 } 716 | '[' ']' slice_count 717 { 718 $$ = $3 + 1 719 } 720 721 expr_member_or_ident : 722 expr_member 723 { 724 $$ = $1 725 } 726 | expr_ident 727 { 728 $$ = $1 729 } 730 731 expr_member : 732 expr '.' IDENT 733 { 734 $$ = &ast.MemberExpr{Expr: $1, Name: $3.Lit} 735 $$.SetPosition($1.Position()) 736 } 737 738 expr_ident : 739 IDENT 740 { 741 $$ = &ast.IdentExpr{Lit: $1.Lit} 742 $$.SetPosition($1.Position()) 743 } 744 745 expr_literals : 746 '-' NUMBER 747 { 748 num, err := toNumber("-" + $2.Lit) 749 if err != nil { 750 yylex.Error("invalid number: -" + $2.Lit) 751 } 752 $$ = &ast.LiteralExpr{Literal: num} 753 $$.SetPosition($2.Position()) 754 } 755 | NUMBER 756 { 757 num, err := toNumber($1.Lit) 758 if err != nil { 759 yylex.Error("invalid number: " + $1.Lit) 760 } 761 $$ = &ast.LiteralExpr{Literal: num} 762 $$.SetPosition($1.Position()) 763 } 764 | STRING 765 { 766 $$ = &ast.LiteralExpr{Literal: stringToValue($1.Lit)} 767 $$.SetPosition($1.Position()) 768 } 769 | TRUE 770 { 771 $$ = &ast.LiteralExpr{Literal: trueValue} 772 $$.SetPosition($1.Position()) 773 } 774 | FALSE 775 { 776 $$ = &ast.LiteralExpr{Literal: falseValue} 777 $$.SetPosition($1.Position()) 778 } 779 | NIL 780 { 781 $$ = &ast.LiteralExpr{Literal: nilValue} 782 $$.SetPosition($1.Position()) 783 } 784 785 expr_map : 786 /* nothing */ 787 { 788 $$ = &ast.MapExpr{} 789 } 790 | expr ':' expr 791 { 792 $$ = &ast.MapExpr{Keys: []ast.Expr{$1}, Values: []ast.Expr{$3}} 793 } 794 | expr_map ',' opt_newlines expr ':' expr 795 { 796 if $1.Keys == nil { 797 yylex.Error("syntax error: unexpected ','") 798 } 799 $$.Keys = append($$.Keys, $4) 800 $$.Values = append($$.Values, $6) 801 } 802 803 expr_slice : 804 expr_ident '[' expr ':' expr ']' 805 { 806 $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: $5} 807 } 808 | expr_ident '[' expr ':' ']' 809 { 810 $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: nil} 811 } 812 | expr_ident '[' ':' expr ']' 813 { 814 $$ = &ast.SliceExpr{Item: $1, Begin: nil, End: $4} 815 } 816 | expr_ident '[' ':' expr ':' expr ']' 817 { 818 $$ = &ast.SliceExpr{Item: $1, End: $4, Cap: $6} 819 } 820 | expr_ident '[' expr ':' expr ':' expr ']' 821 { 822 $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: $5, Cap: $7} 823 } 824 | expr '[' expr ':' expr ']' 825 { 826 $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: $5} 827 } 828 | expr '[' expr ':' ']' 829 { 830 $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: nil} 831 } 832 | expr '[' ':' expr ']' 833 { 834 $$ = &ast.SliceExpr{Item: $1, Begin: nil, End: $4} 835 } 836 | expr '[' ':' expr ':' expr ']' 837 { 838 $$ = &ast.SliceExpr{Item: $1, End: $4, Cap: $6} 839 } 840 | expr '[' expr ':' expr ':' expr ']' 841 { 842 $$ = &ast.SliceExpr{Item: $1, Begin: $3, End: $5, Cap: $7} 843 } 844 845 expr_chan : 846 expr OPCHAN expr 847 { 848 $$ = &ast.ChanExpr{LHS: $1, RHS: $3} 849 } 850 | OPCHAN expr 851 { 852 $$ = &ast.ChanExpr{RHS: $2} 853 } 854 855 expr_unary : 856 '-' expr %prec UNARY 857 { 858 $$ = &ast.UnaryExpr{Operator: "-", Expr: $2} 859 $$.SetPosition($2.Position()) 860 } 861 | '!' expr %prec UNARY 862 { 863 $$ = &ast.UnaryExpr{Operator: "!", Expr: $2} 864 $$.SetPosition($2.Position()) 865 } 866 | '^' expr %prec UNARY 867 { 868 $$ = &ast.UnaryExpr{Operator: "^", Expr: $2} 869 $$.SetPosition($2.Position()) 870 } 871 | '&' expr %prec UNARY 872 { 873 $$ = &ast.AddrExpr{Expr: $2} 874 $$.SetPosition($2.Position()) 875 } 876 | '*' expr %prec UNARY 877 { 878 $$ = &ast.DerefExpr{Expr: $2} 879 $$.SetPosition($2.Position()) 880 } 881 882 expr_binary : 883 op_multiply 884 { 885 $$ = &ast.OpExpr{Op: $1} 886 $$.SetPosition($1.Position()) 887 } 888 | op_add 889 { 890 $$ = &ast.OpExpr{Op: $1} 891 $$.SetPosition($1.Position()) 892 } 893 | op_comparison 894 { 895 $$ = &ast.OpExpr{Op: $1} 896 $$.SetPosition($1.Position()) 897 } 898 | op_binary 899 { 900 $$ = &ast.OpExpr{Op: $1} 901 $$.SetPosition($1.Position()) 902 } 903 904 expr_lets: 905 expr PLUSPLUS 906 { 907 rhs := &ast.OpExpr{Op: &ast.AddOperator{LHS: $1, Operator: "+", RHS: oneLiteral}} 908 rhs.Op.SetPosition($1.Position()) 909 rhs.SetPosition($1.Position()) 910 $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}} 911 $$.SetPosition($1.Position()) 912 } 913 | expr MINUSMINUS 914 { 915 rhs := &ast.OpExpr{Op: &ast.AddOperator{LHS: $1, Operator: "-", RHS: oneLiteral}} 916 rhs.Op.SetPosition($1.Position()) 917 rhs.SetPosition($1.Position()) 918 $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}} 919 $$.SetPosition($1.Position()) 920 } 921 | expr PLUSEQ expr 922 { 923 rhs := &ast.OpExpr{Op: &ast.AddOperator{LHS: $1, Operator: "+", RHS: $3}} 924 rhs.Op.SetPosition($1.Position()) 925 rhs.SetPosition($1.Position()) 926 $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}} 927 $$.SetPosition($1.Position()) 928 } 929 | expr MINUSEQ expr 930 { 931 rhs := &ast.OpExpr{Op: &ast.AddOperator{LHS: $1, Operator: "-", RHS: $3}} 932 rhs.Op.SetPosition($1.Position()) 933 rhs.SetPosition($1.Position()) 934 $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}} 935 $$.SetPosition($1.Position()) 936 } 937 | expr OREQ expr 938 { 939 rhs := &ast.OpExpr{Op: &ast.AddOperator{LHS: $1, Operator: "|", RHS: $3}} 940 rhs.Op.SetPosition($1.Position()) 941 rhs.SetPosition($1.Position()) 942 $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}} 943 $$.SetPosition($1.Position()) 944 } 945 | expr MULEQ expr 946 { 947 rhs := &ast.OpExpr{Op: &ast.MultiplyOperator{LHS: $1, Operator: "*", RHS: $3}} 948 rhs.Op.SetPosition($1.Position()) 949 rhs.SetPosition($1.Position()) 950 $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}} 951 $$.SetPosition($1.Position()) 952 } 953 | expr DIVEQ expr 954 { 955 rhs := &ast.OpExpr{Op: &ast.MultiplyOperator{LHS: $1, Operator: "/", RHS: $3}} 956 rhs.Op.SetPosition($1.Position()) 957 rhs.SetPosition($1.Position()) 958 $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}} 959 $$.SetPosition($1.Position()) 960 } 961 | expr ANDEQ expr 962 { 963 rhs := &ast.OpExpr{Op: &ast.MultiplyOperator{LHS: $1, Operator: "&", RHS: $3}} 964 rhs.Op.SetPosition($1.Position()) 965 rhs.SetPosition($1.Position()) 966 $$ = &ast.LetsExpr{LHSS: []ast.Expr{$1}, RHSS: []ast.Expr{rhs}} 967 $$.SetPosition($1.Position()) 968 } 969 970 971 op_multiply : 972 expr '*' expr 973 { 974 $$ = &ast.MultiplyOperator{LHS: $1, Operator: "*", RHS: $3} 975 $$.SetPosition($1.Position()) 976 } 977 | expr '/' expr 978 { 979 $$ = &ast.MultiplyOperator{LHS: $1, Operator: "/", RHS: $3} 980 $$.SetPosition($1.Position()) 981 } 982 | expr '%' expr 983 { 984 $$ = &ast.MultiplyOperator{LHS: $1, Operator: "%", RHS: $3} 985 $$.SetPosition($1.Position()) 986 } 987 | expr SHIFTLEFT expr 988 { 989 $$ = &ast.MultiplyOperator{LHS: $1, Operator: "<<", RHS: $3} 990 $$.SetPosition($1.Position()) 991 } 992 | expr SHIFTRIGHT expr 993 { 994 $$ = &ast.MultiplyOperator{LHS: $1, Operator: ">>", RHS: $3} 995 $$.SetPosition($1.Position()) 996 } 997 | expr '&' expr 998 { 999 $$ = &ast.MultiplyOperator{LHS: $1, Operator: "&", RHS: $3} 1000 $$.SetPosition($1.Position()) 1001 } 1002 1003 op_add : 1004 expr '+' expr 1005 { 1006 $$ = &ast.AddOperator{LHS: $1, Operator: "+", RHS: $3} 1007 $$.SetPosition($1.Position()) 1008 } 1009 | expr '-' expr 1010 { 1011 $$ = &ast.AddOperator{LHS: $1, Operator: "-", RHS: $3} 1012 $$.SetPosition($1.Position()) 1013 } 1014 | expr '|' expr 1015 { 1016 $$ = &ast.AddOperator{LHS: $1, Operator: "|", RHS: $3} 1017 $$.SetPosition($1.Position()) 1018 } 1019 1020 op_comparison : 1021 expr EQEQ expr 1022 { 1023 $$ = &ast.ComparisonOperator{LHS: $1, Operator: "==", RHS: $3} 1024 $$.SetPosition($1.Position()) 1025 } 1026 | expr NEQ expr 1027 { 1028 $$ = &ast.ComparisonOperator{LHS: $1, Operator: "!=", RHS: $3} 1029 $$.SetPosition($1.Position()) 1030 } 1031 | expr '<' expr 1032 { 1033 $$ = &ast.ComparisonOperator{LHS: $1, Operator: "<", RHS: $3} 1034 $$.SetPosition($1.Position()) 1035 } 1036 | expr LE expr 1037 { 1038 $$ = &ast.ComparisonOperator{LHS: $1, Operator: "<=", RHS: $3} 1039 $$.SetPosition($1.Position()) 1040 } 1041 | expr '>' expr 1042 { 1043 $$ = &ast.ComparisonOperator{LHS: $1, Operator: ">", RHS: $3} 1044 $$.SetPosition($1.Position()) 1045 } 1046 | expr GE expr 1047 { 1048 $$ = &ast.ComparisonOperator{LHS: $1, Operator: ">=", RHS: $3} 1049 $$.SetPosition($1.Position()) 1050 } 1051 1052 op_binary : 1053 expr ANDAND expr 1054 { 1055 $$ = &ast.BinaryOperator{LHS: $1, Operator: "&&", RHS: $3} 1056 $$.SetPosition($1.Position()) 1057 } 1058 | expr OROR expr 1059 { 1060 $$ = &ast.BinaryOperator{LHS: $1, Operator: "||", RHS: $3} 1061 $$.SetPosition($1.Position()) 1062 } 1063 1064 1065 opt_term : 1066 /* nothing */ 1067 | term 1068 1069 term : 1070 ';' newlines 1071 | newlines 1072 | ';' 1073 1074 opt_newlines : 1075 /* nothing */ 1076 | newlines 1077 1078 newlines : 1079 newline 1080 | newlines newline 1081 1082 newline : '\n' 1083 1084 opt_comma_newlines : 1085 /* nothing */ 1086 | ',' newlines 1087 | newlines 1088 | ',' 1089 1090 %%