github.com/jhump/protocompile@v0.0.0-20221021153901-4f6f732835e8/parser/proto.y (about) 1 %{ 2 package parser 3 4 //lint:file-ignore SA4006 generated parser has unused values 5 6 import ( 7 "math" 8 9 "github.com/jhump/protocompile/ast" 10 ) 11 12 %} 13 14 // fields inside this union end up as the fields in a structure known 15 // as ${PREFIX}SymType, of which a reference is passed to the lexer. 16 %union{ 17 file *ast.FileNode 18 syn *ast.SyntaxNode 19 fileDecl ast.FileElement 20 fileDecls []ast.FileElement 21 pkg *ast.PackageNode 22 imprt *ast.ImportNode 23 msg *ast.MessageNode 24 msgDecl ast.MessageElement 25 msgDecls []ast.MessageElement 26 fld *ast.FieldNode 27 mapFld *ast.MapFieldNode 28 mapType *ast.MapTypeNode 29 grp *ast.GroupNode 30 oo *ast.OneOfNode 31 ooDecl ast.OneOfElement 32 ooDecls []ast.OneOfElement 33 ext *ast.ExtensionRangeNode 34 resvd *ast.ReservedNode 35 en *ast.EnumNode 36 enDecl ast.EnumElement 37 enDecls []ast.EnumElement 38 env *ast.EnumValueNode 39 extend *ast.ExtendNode 40 extDecl ast.ExtendElement 41 extDecls []ast.ExtendElement 42 svc *ast.ServiceNode 43 svcDecl ast.ServiceElement 44 svcDecls []ast.ServiceElement 45 mtd *ast.RPCNode 46 rpcType *ast.RPCTypeNode 47 rpcDecl ast.RPCElement 48 rpcDecls []ast.RPCElement 49 opt *ast.OptionNode 50 opts *compactOptionList 51 ref *ast.FieldReferenceNode 52 optNms *fieldRefList 53 cmpctOpts *ast.CompactOptionsNode 54 rng *ast.RangeNode 55 rngs *rangeList 56 names *nameList 57 cid *identList 58 tid ast.IdentValueNode 59 sl *valueList 60 msgField *ast.MessageFieldNode 61 msgEntry *messageFieldEntry 62 msgLit *messageFieldList 63 v ast.ValueNode 64 il ast.IntValueNode 65 str *stringList 66 s *ast.StringLiteralNode 67 i *ast.UintLiteralNode 68 f *ast.FloatLiteralNode 69 id *ast.IdentNode 70 b *ast.RuneNode 71 err error 72 } 73 74 // any non-terminal which returns a value needs a type, which is 75 // really a field name in the above union struct 76 %type <file> file 77 %type <syn> syntax 78 %type <fileDecl> fileDecl 79 %type <fileDecls> fileDecls 80 %type <imprt> import 81 %type <pkg> package 82 %type <opt> option compactOption 83 %type <opts> compactOptionDecls 84 %type <rpcDecl> rpcDecl 85 %type <rpcDecls> rpcDecls 86 %type <ref> optionNameComponent aggName 87 %type <optNms> optionName 88 %type <cmpctOpts> compactOptions 89 %type <v> constant scalarConstant aggregate numLit 90 %type <il> intLit 91 %type <id> name keyType msgElementName extElementName oneofElementName enumElementName 92 %type <cid> ident msgElementIdent extElementIdent oneofElementIdent 93 %type <tid> typeIdent msgElementTypeIdent extElementTypeIdent oneofElementTypeIdent 94 %type <sl> constantList 95 %type <msgField> aggFieldEntry 96 %type <msgEntry> aggField 97 %type <msgLit> aggFields 98 %type <fld> msgField oneofField extField 99 %type <oo> oneof 100 %type <grp> group oneofGroup 101 %type <mapFld> mapField 102 %type <mapType> mapType 103 %type <msg> message 104 %type <msgDecl> messageDecl 105 %type <msgDecls> messageDecls 106 %type <ooDecl> ooDecl 107 %type <ooDecls> ooDecls 108 %type <names> fieldNames 109 %type <resvd> msgReserved enumReserved reservedNames 110 %type <rng> tagRange enumRange 111 %type <rngs> tagRanges enumRanges 112 %type <ext> extensions 113 %type <en> enum 114 %type <enDecl> enumDecl 115 %type <enDecls> enumDecls 116 %type <env> enumValue 117 %type <extend> extend 118 %type <extDecl> extendDecl 119 %type <extDecls> extendDecls 120 %type <str> stringLit 121 %type <svc> service 122 %type <svcDecl> serviceDecl 123 %type <svcDecls> serviceDecls 124 %type <mtd> rpc 125 %type <rpcType> rpcType 126 127 // same for terminals 128 %token <s> _STRING_LIT 129 %token <i> _INT_LIT 130 %token <f> _FLOAT_LIT 131 %token <id> _NAME 132 %token <id> _SYNTAX _IMPORT _WEAK _PUBLIC _PACKAGE _OPTION _TRUE _FALSE _INF _NAN _REPEATED _OPTIONAL _REQUIRED 133 %token <id> _DOUBLE _FLOAT _INT32 _INT64 _UINT32 _UINT64 _SINT32 _SINT64 _FIXED32 _FIXED64 _SFIXED32 _SFIXED64 134 %token <id> _BOOL _STRING _BYTES _GROUP _ONEOF _MAP _EXTENSIONS _TO _MAX _RESERVED _ENUM _MESSAGE _EXTEND 135 %token <id> _SERVICE _RPC _STREAM _RETURNS 136 %token <err> _ERROR 137 // we define all of these, even ones that aren't used, to improve error messages 138 // so it shows the unexpected symbol instead of showing "$unk" 139 %token <b> '=' ';' ':' '{' '}' '\\' '/' '?' '.' ',' '>' '<' '+' '-' '(' ')' '[' ']' '*' '&' '^' '%' '$' '#' '@' '!' '~' '`' 140 141 %% 142 143 file : syntax { 144 lex := protolex.(*protoLex) 145 $$ = ast.NewFileNode(lex.info, $1, nil, lex.eof) 146 lex.res = $$ 147 } 148 | fileDecls { 149 lex := protolex.(*protoLex) 150 $$ = ast.NewFileNode(lex.info, nil, $1, lex.eof) 151 lex.res = $$ 152 } 153 | syntax fileDecls { 154 lex := protolex.(*protoLex) 155 $$ = ast.NewFileNode(lex.info, $1, $2, lex.eof) 156 lex.res = $$ 157 } 158 | { 159 } 160 161 fileDecls : fileDecls fileDecl { 162 if $2 != nil { 163 $$ = append($1, $2) 164 } else { 165 $$ = $1 166 } 167 } 168 | fileDecl { 169 if $1 != nil { 170 $$ = []ast.FileElement{$1} 171 } else { 172 $$ = nil 173 } 174 } 175 176 fileDecl : import { 177 $$ = $1 178 } 179 | package { 180 $$ = $1 181 } 182 | option { 183 $$ = $1 184 } 185 | message { 186 $$ = $1 187 } 188 | enum { 189 $$ = $1 190 } 191 | extend { 192 $$ = $1 193 } 194 | service { 195 $$ = $1 196 } 197 | ';' { 198 $$ = ast.NewEmptyDeclNode($1) 199 } 200 | error ';' { 201 $$ = nil 202 } 203 | error { 204 $$ = nil 205 } 206 207 syntax : _SYNTAX '=' stringLit ';' { 208 $$ = ast.NewSyntaxNode($1.ToKeyword(), $2, $3.toStringValueNode(), $4) 209 } 210 211 import : _IMPORT stringLit ';' { 212 $$ = ast.NewImportNode($1.ToKeyword(), nil, nil, $2.toStringValueNode(), $3) 213 } 214 | _IMPORT _WEAK stringLit ';' { 215 $$ = ast.NewImportNode($1.ToKeyword(), nil, $2.ToKeyword(), $3.toStringValueNode(), $4) 216 } 217 | _IMPORT _PUBLIC stringLit ';' { 218 $$ = ast.NewImportNode($1.ToKeyword(), $2.ToKeyword(), nil, $3.toStringValueNode(), $4) 219 } 220 221 package : _PACKAGE ident ';' { 222 $$ = ast.NewPackageNode($1.ToKeyword(), $2.toIdentValueNode(nil), $3) 223 } 224 225 ident : name { 226 $$ = &identList{$1, nil, nil} 227 } 228 | name '.' ident { 229 $$ = &identList{$1, $2, $3} 230 } 231 232 // to mimic limitations of protoc recursive-descent parser, 233 // we don't allowed message statement keywords as identifiers 234 // (or oneof statement keywords [e.g. "option"] below) 235 236 msgElementIdent : msgElementName { 237 $$ = &identList{$1, nil, nil} 238 } 239 | msgElementName '.' ident { 240 $$ = &identList{$1, $2, $3} 241 } 242 243 extElementIdent : extElementName { 244 $$ = &identList{$1, nil, nil} 245 } 246 | extElementName '.' ident { 247 $$ = &identList{$1, $2, $3} 248 } 249 250 oneofElementIdent : oneofElementName { 251 $$ = &identList{$1, nil, nil} 252 } 253 | oneofElementName '.' ident { 254 $$ = &identList{$1, $2, $3} 255 } 256 257 option : _OPTION optionName '=' constant ';' { 258 refs, dots := $2.toNodes() 259 optName := ast.NewOptionNameNode(refs, dots) 260 $$ = ast.NewOptionNode($1.ToKeyword(), optName, $3, $4, $5) 261 } 262 263 optionName : optionNameComponent { 264 $$ = &fieldRefList{$1, nil, nil} 265 } 266 | optionNameComponent '.' optionName { 267 $$ = &fieldRefList{$1, $2, $3} 268 } 269 270 optionNameComponent : name { 271 $$ = ast.NewFieldReferenceNode($1) 272 } 273 | '(' typeIdent ')' { 274 $$ = ast.NewExtensionFieldReferenceNode($1, $2, $3) 275 } 276 277 constant : scalarConstant 278 | aggregate 279 280 scalarConstant : stringLit { 281 $$ = $1.toStringValueNode() 282 } 283 | numLit 284 | name { 285 if $1.Val == "true" || $1.Val == "false" { 286 $$ = ast.NewBoolLiteralNode($1.ToKeyword()) 287 } else if $1.Val == "inf" || $1.Val == "nan" { 288 $$ = ast.NewSpecialFloatLiteralNode($1.ToKeyword()) 289 } else { 290 $$ = $1 291 } 292 } 293 294 numLit : _FLOAT_LIT { 295 $$ = $1 296 } 297 | '-' _FLOAT_LIT { 298 $$ = ast.NewSignedFloatLiteralNode($1, $2) 299 } 300 | '+' _FLOAT_LIT { 301 $$ = ast.NewSignedFloatLiteralNode($1, $2) 302 } 303 | '+' _INF { 304 f := ast.NewSpecialFloatLiteralNode($2.ToKeyword()) 305 $$ = ast.NewSignedFloatLiteralNode($1, f) 306 } 307 | '-' _INF { 308 f := ast.NewSpecialFloatLiteralNode($2.ToKeyword()) 309 $$ = ast.NewSignedFloatLiteralNode($1, f) 310 } 311 | _INT_LIT { 312 $$ = $1 313 } 314 | '+' _INT_LIT { 315 $$ = ast.NewPositiveUintLiteralNode($1, $2) 316 } 317 | '-' _INT_LIT { 318 if $2.Val > math.MaxInt64 + 1 { 319 // can't represent as int so treat as float literal 320 $$ = ast.NewSignedFloatLiteralNode($1, $2) 321 } else { 322 $$ = ast.NewNegativeIntLiteralNode($1, $2) 323 } 324 } 325 326 stringLit : _STRING_LIT { 327 $$ = &stringList{$1, nil} 328 } 329 | _STRING_LIT stringLit { 330 $$ = &stringList{$1, $2} 331 } 332 333 aggregate : '{' aggFields '}' { 334 fields, delims := $2.toNodes() 335 $$ = ast.NewMessageLiteralNode($1, fields, delims, $3) 336 } 337 338 aggFields : aggField { 339 if $1 != nil { 340 $$ = &messageFieldList{$1, nil} 341 } else { 342 $$ = nil 343 } 344 } 345 | aggField aggFields { 346 if $1 != nil { 347 $$ = &messageFieldList{$1, $2} 348 } else { 349 $$ = $2 350 } 351 } 352 | { 353 $$ = nil 354 } 355 356 aggField : aggFieldEntry { 357 if $1 != nil { 358 $$ = &messageFieldEntry{$1, nil} 359 } else { 360 $$ = nil 361 } 362 } 363 | aggFieldEntry ',' { 364 if $1 != nil { 365 $$ = &messageFieldEntry{$1, $2} 366 } else { 367 $$ = nil 368 } 369 } 370 | aggFieldEntry ';' { 371 if $1 != nil { 372 $$ = &messageFieldEntry{$1, $2} 373 } else { 374 $$ = nil 375 } 376 } 377 | error ',' { 378 $$ = nil 379 } 380 | error ';' { 381 $$ = nil 382 } 383 | error { 384 $$ = nil 385 } 386 387 aggFieldEntry : aggName ':' scalarConstant { 388 if $1 != nil { 389 $$ = ast.NewMessageFieldNode($1, $2, $3) 390 } else { 391 $$ = nil 392 } 393 } 394 | aggName '[' ']' { 395 if $1 != nil { 396 val := ast.NewArrayLiteralNode($2, nil, nil, $3) 397 $$ = ast.NewMessageFieldNode($1, nil, val) 398 } else { 399 $$ = nil 400 } 401 } 402 | aggName ':' '[' ']' { 403 if $1 != nil { 404 val := ast.NewArrayLiteralNode($3, nil, nil, $4) 405 $$ = ast.NewMessageFieldNode($1, $2, val) 406 } else { 407 $$ = nil 408 } 409 } 410 | aggName '[' constantList ']' { 411 if $1 != nil { 412 vals, commas := $3.toNodes() 413 val := ast.NewArrayLiteralNode($2, vals, commas, $4) 414 $$ = ast.NewMessageFieldNode($1, nil, val) 415 } else { 416 $$ = nil 417 } 418 } 419 | aggName ':' '[' constantList ']' { 420 if $1 != nil { 421 vals, commas := $4.toNodes() 422 val := ast.NewArrayLiteralNode($3, vals, commas, $5) 423 $$ = ast.NewMessageFieldNode($1, $2, val) 424 } else { 425 $$ = nil 426 } 427 } 428 | aggName ':' '[' error ']' { 429 $$ = nil 430 } 431 | aggName ':' aggregate { 432 if $1 != nil { 433 $$ = ast.NewMessageFieldNode($1, $2, $3) 434 } else { 435 $$ = nil 436 } 437 } 438 | aggName aggregate { 439 if $1 != nil { 440 $$ = ast.NewMessageFieldNode($1, nil, $2) 441 } else { 442 $$ = nil 443 } 444 } 445 | aggName ':' '<' aggFields '>' { 446 if $1 != nil { 447 fields, delims := $4.toNodes() 448 msg := ast.NewMessageLiteralNode($3, fields, delims, $5) 449 $$ = ast.NewMessageFieldNode($1, $2, msg) 450 } else { 451 $$ = nil 452 } 453 } 454 | aggName '<' aggFields '>' { 455 if $1 != nil { 456 fields, delims := $3.toNodes() 457 msg := ast.NewMessageLiteralNode($2, fields, delims, $4) 458 $$ = ast.NewMessageFieldNode($1, nil, msg) 459 } else { 460 $$ = nil 461 } 462 } 463 | aggName ':' '<' error '>' { 464 $$ = nil 465 } 466 | aggName '<' error '>' { 467 $$ = nil 468 } 469 470 aggName : name { 471 $$ = ast.NewFieldReferenceNode($1) 472 } 473 | '[' typeIdent ']' { 474 $$ = ast.NewExtensionFieldReferenceNode($1, $2, $3) 475 } 476 | '[' error ']' { 477 $$ = nil 478 } 479 480 constantList : constant { 481 $$ = &valueList{$1, nil, nil} 482 } 483 | constant ',' constantList { 484 $$ = &valueList{$1, $2, $3} 485 } 486 | '<' aggFields '>' { 487 fields, delims := $2.toNodes() 488 msg := ast.NewMessageLiteralNode($1, fields, delims, $3) 489 $$ = &valueList{msg, nil, nil} 490 } 491 | '<' aggFields '>' ',' constantList { 492 fields, delims := $2.toNodes() 493 msg := ast.NewMessageLiteralNode($1, fields, delims, $3) 494 $$ = &valueList{msg, $4, $5} 495 } 496 | '<' error '>' { 497 $$ = nil 498 } 499 | '<' error '>' ',' constantList { 500 $$ = $5 501 } 502 503 typeIdent : ident { 504 $$ = $1.toIdentValueNode(nil) 505 } 506 | '.' ident { 507 $$ = $2.toIdentValueNode($1) 508 } 509 510 msgElementTypeIdent : msgElementIdent { 511 $$ = $1.toIdentValueNode(nil) 512 } 513 | '.' ident { 514 $$ = $2.toIdentValueNode($1) 515 } 516 517 extElementTypeIdent : extElementIdent { 518 $$ = $1.toIdentValueNode(nil) 519 } 520 | '.' ident { 521 $$ = $2.toIdentValueNode($1) 522 } 523 524 oneofElementTypeIdent : oneofElementIdent { 525 $$ = $1.toIdentValueNode(nil) 526 } 527 | '.' ident { 528 $$ = $2.toIdentValueNode($1) 529 } 530 531 msgField : _REQUIRED typeIdent name '=' _INT_LIT ';' { 532 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6) 533 } 534 | _OPTIONAL typeIdent name '=' _INT_LIT ';' { 535 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6) 536 } 537 | _REPEATED typeIdent name '=' _INT_LIT ';' { 538 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6) 539 } 540 | _REQUIRED typeIdent name '=' _INT_LIT compactOptions ';' { 541 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7) 542 } 543 | _OPTIONAL typeIdent name '=' _INT_LIT compactOptions ';' { 544 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7) 545 } 546 | _REPEATED typeIdent name '=' _INT_LIT compactOptions ';' { 547 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7) 548 } 549 | msgElementTypeIdent name '=' _INT_LIT ';' { 550 $$ = ast.NewFieldNode(nil, $1, $2, $3, $4, nil, $5) 551 } 552 | msgElementTypeIdent name '=' _INT_LIT compactOptions ';' { 553 $$ = ast.NewFieldNode(nil, $1, $2, $3, $4, $5, $6) 554 } 555 556 extField : _REQUIRED typeIdent name '=' _INT_LIT ';' { 557 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6) 558 } 559 | _OPTIONAL typeIdent name '=' _INT_LIT ';' { 560 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6) 561 } 562 | _REPEATED typeIdent name '=' _INT_LIT ';' { 563 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, nil, $6) 564 } 565 | _REQUIRED typeIdent name '=' _INT_LIT compactOptions ';' { 566 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7) 567 } 568 | _OPTIONAL typeIdent name '=' _INT_LIT compactOptions ';' { 569 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7) 570 } 571 | _REPEATED typeIdent name '=' _INT_LIT compactOptions ';' { 572 $$ = ast.NewFieldNode($1.ToKeyword(), $2, $3, $4, $5, $6, $7) 573 } 574 | extElementTypeIdent name '=' _INT_LIT ';' { 575 $$ = ast.NewFieldNode(nil, $1, $2, $3, $4, nil, $5) 576 } 577 | extElementTypeIdent name '=' _INT_LIT compactOptions ';' { 578 $$ = ast.NewFieldNode(nil, $1, $2, $3, $4, $5, $6) 579 } 580 581 compactOptions: '[' compactOptionDecls ']' { 582 opts, commas := $2.toNodes() 583 $$ = ast.NewCompactOptionsNode($1, opts, commas, $3) 584 } 585 586 compactOptionDecls : compactOption { 587 $$ = &compactOptionList{$1, nil, nil} 588 } 589 | compactOption ',' compactOptionDecls { 590 $$ = &compactOptionList{$1, $2, $3} 591 } 592 593 compactOption: optionName '=' constant { 594 refs, dots := $1.toNodes() 595 optName := ast.NewOptionNameNode(refs, dots) 596 $$ = ast.NewCompactOptionNode(optName, $2, $3) 597 } 598 599 group : _REQUIRED _GROUP name '=' _INT_LIT '{' messageDecls '}' { 600 $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, nil, $6, $7, $8) 601 } 602 | _OPTIONAL _GROUP name '=' _INT_LIT '{' messageDecls '}' { 603 $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, nil, $6, $7, $8) 604 } 605 | _REPEATED _GROUP name '=' _INT_LIT '{' messageDecls '}' { 606 $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, nil, $6, $7, $8) 607 } 608 | _REQUIRED _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' { 609 $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, $6, $7, $8, $9) 610 } 611 | _OPTIONAL _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' { 612 $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, $6, $7, $8, $9) 613 } 614 | _REPEATED _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' { 615 $$ = ast.NewGroupNode($1.ToKeyword(), $2.ToKeyword(), $3, $4, $5, $6, $7, $8, $9) 616 } 617 618 oneof : _ONEOF name '{' ooDecls '}' { 619 $$ = ast.NewOneOfNode($1.ToKeyword(), $2, $3, $4, $5) 620 } 621 622 ooDecls : ooDecls ooDecl { 623 if $2 != nil { 624 $$ = append($1, $2) 625 } else { 626 $$ = $1 627 } 628 } 629 | ooDecl { 630 if $1 != nil { 631 $$ = []ast.OneOfElement{$1} 632 } else { 633 $$ = nil 634 } 635 } 636 | { 637 $$ = nil 638 } 639 640 ooDecl : option { 641 $$ = $1 642 } 643 | oneofField { 644 $$ = $1 645 } 646 | oneofGroup { 647 $$ = $1 648 } 649 | ';' { 650 $$ = ast.NewEmptyDeclNode($1) 651 } 652 | error ';' { 653 $$ = nil 654 } 655 | error { 656 $$ = nil 657 } 658 659 oneofField : oneofElementTypeIdent name '=' _INT_LIT ';' { 660 $$ = ast.NewFieldNode(nil, $1, $2, $3, $4, nil, $5) 661 } 662 | oneofElementTypeIdent name '=' _INT_LIT compactOptions ';' { 663 $$ = ast.NewFieldNode(nil, $1, $2, $3, $4, $5, $6) 664 } 665 666 oneofGroup : _GROUP name '=' _INT_LIT '{' messageDecls '}' { 667 $$ = ast.NewGroupNode(nil, $1.ToKeyword(), $2, $3, $4, nil, $5, $6, $7) 668 } 669 | _GROUP name '=' _INT_LIT compactOptions '{' messageDecls '}' { 670 $$ = ast.NewGroupNode(nil, $1.ToKeyword(), $2, $3, $4, $5, $6, $7, $8) 671 } 672 673 mapField : mapType name '=' _INT_LIT ';' { 674 $$ = ast.NewMapFieldNode($1, $2, $3, $4, nil, $5) 675 } 676 | mapType name '=' _INT_LIT compactOptions ';' { 677 $$ = ast.NewMapFieldNode($1, $2, $3, $4, $5, $6) 678 } 679 680 mapType : _MAP '<' keyType ',' typeIdent '>' { 681 $$ = ast.NewMapTypeNode($1.ToKeyword(), $2, $3, $4, $5, $6) 682 } 683 684 keyType : _INT32 685 | _INT64 686 | _UINT32 687 | _UINT64 688 | _SINT32 689 | _SINT64 690 | _FIXED32 691 | _FIXED64 692 | _SFIXED32 693 | _SFIXED64 694 | _BOOL 695 | _STRING 696 697 extensions : _EXTENSIONS tagRanges ';' { 698 ranges, commas := $2.toNodes() 699 $$ = ast.NewExtensionRangeNode($1.ToKeyword(), ranges, commas, nil, $3) 700 } 701 | _EXTENSIONS tagRanges compactOptions ';' { 702 ranges, commas := $2.toNodes() 703 $$ = ast.NewExtensionRangeNode($1.ToKeyword(), ranges, commas, $3, $4) 704 } 705 706 tagRanges : tagRange { 707 $$ = &rangeList{$1, nil, nil} 708 } 709 | tagRange ',' tagRanges { 710 $$ = &rangeList{$1, $2, $3} 711 } 712 713 tagRange : _INT_LIT { 714 $$ = ast.NewRangeNode($1, nil, nil, nil) 715 } 716 | _INT_LIT _TO _INT_LIT { 717 $$ = ast.NewRangeNode($1, $2.ToKeyword(), $3, nil) 718 } 719 | _INT_LIT _TO _MAX { 720 $$ = ast.NewRangeNode($1, $2.ToKeyword(), nil, $3.ToKeyword()) 721 } 722 723 enumRanges : enumRange { 724 $$ = &rangeList{$1, nil, nil} 725 } 726 | enumRange ',' enumRanges { 727 $$ = &rangeList{$1, $2, $3} 728 } 729 730 enumRange : intLit { 731 $$ = ast.NewRangeNode($1, nil, nil, nil) 732 } 733 | intLit _TO intLit { 734 $$ = ast.NewRangeNode($1, $2.ToKeyword(), $3, nil) 735 } 736 | intLit _TO _MAX { 737 $$ = ast.NewRangeNode($1, $2.ToKeyword(), nil, $3.ToKeyword()) 738 } 739 740 intLit : _INT_LIT { 741 $$ = $1 742 } 743 | '-' _INT_LIT { 744 $$ = ast.NewNegativeIntLiteralNode($1, $2) 745 } 746 747 msgReserved : _RESERVED tagRanges ';' { 748 ranges, commas := $2.toNodes() 749 $$ = ast.NewReservedRangesNode($1.ToKeyword(), ranges, commas, $3) 750 } 751 | reservedNames 752 753 enumReserved : _RESERVED enumRanges ';' { 754 ranges, commas := $2.toNodes() 755 $$ = ast.NewReservedRangesNode($1.ToKeyword(), ranges, commas, $3) 756 } 757 | reservedNames 758 759 reservedNames : _RESERVED fieldNames ';' { 760 names, commas := $2.toNodes() 761 $$ = ast.NewReservedNamesNode($1.ToKeyword(), names, commas, $3) 762 } 763 764 fieldNames : stringLit { 765 $$ = &nameList{$1.toStringValueNode(), nil, nil} 766 } 767 | stringLit ',' fieldNames { 768 $$ = &nameList{$1.toStringValueNode(), $2, $3} 769 } 770 771 enum : _ENUM name '{' enumDecls '}' { 772 $$ = ast.NewEnumNode($1.ToKeyword(), $2, $3, $4, $5) 773 } 774 775 enumDecls : enumDecls enumDecl { 776 if $2 != nil { 777 $$ = append($1, $2) 778 } else { 779 $$ = $1 780 } 781 } 782 | enumDecl { 783 if $1 != nil { 784 $$ = []ast.EnumElement{$1} 785 } else { 786 $$ = nil 787 } 788 } 789 | { 790 $$ = nil 791 } 792 793 enumDecl : option { 794 $$ = $1 795 } 796 | enumValue { 797 $$ = $1 798 } 799 | enumReserved { 800 $$ = $1 801 } 802 | ';' { 803 $$ = ast.NewEmptyDeclNode($1) 804 } 805 | error ';' { 806 $$ = nil 807 } 808 | error { 809 $$ = nil 810 } 811 812 enumValue : enumElementName '=' intLit ';' { 813 $$ = ast.NewEnumValueNode($1, $2, $3, nil, $4) 814 } 815 | enumElementName '=' intLit compactOptions ';' { 816 $$ = ast.NewEnumValueNode($1, $2, $3, $4, $5) 817 } 818 819 message : _MESSAGE name '{' messageDecls '}' { 820 $$ = ast.NewMessageNode($1.ToKeyword(), $2, $3, $4, $5) 821 } 822 823 messageDecls : messageDecls messageDecl { 824 if $2 != nil { 825 $$ = append($1, $2) 826 } else { 827 $$ = $1 828 } 829 } 830 | messageDecl { 831 if $1 != nil { 832 $$ = []ast.MessageElement{$1} 833 } else { 834 $$ = nil 835 } 836 } 837 | { 838 $$ = nil 839 } 840 841 messageDecl : msgField { 842 $$ = $1 843 } 844 | enum { 845 $$ = $1 846 } 847 | message { 848 $$ = $1 849 } 850 | extend { 851 $$ = $1 852 } 853 | extensions { 854 $$ = $1 855 } 856 | group { 857 $$ = $1 858 } 859 | option { 860 $$ = $1 861 } 862 | oneof { 863 $$ = $1 864 } 865 | mapField { 866 $$ = $1 867 } 868 | msgReserved { 869 $$ = $1 870 } 871 | ';' { 872 $$ = ast.NewEmptyDeclNode($1) 873 } 874 | error ';' { 875 $$ = nil 876 } 877 | error { 878 $$ = nil 879 } 880 881 extend : _EXTEND typeIdent '{' extendDecls '}' { 882 $$ = ast.NewExtendNode($1.ToKeyword(), $2, $3, $4, $5) 883 } 884 885 extendDecls : extendDecls extendDecl { 886 if $2 != nil { 887 $$ = append($1, $2) 888 } else { 889 $$ = $1 890 } 891 } 892 | extendDecl { 893 if $1 != nil { 894 $$ = []ast.ExtendElement{$1} 895 } else { 896 $$ = nil 897 } 898 } 899 | { 900 $$ = nil 901 } 902 903 extendDecl : extField { 904 $$ = $1 905 } 906 | group { 907 $$ = $1 908 } 909 | ';' { 910 $$ = ast.NewEmptyDeclNode($1) 911 } 912 | error ';' { 913 $$ = nil 914 } 915 | error { 916 $$ = nil 917 } 918 919 service : _SERVICE name '{' serviceDecls '}' { 920 $$ = ast.NewServiceNode($1.ToKeyword(), $2, $3, $4, $5) 921 } 922 923 serviceDecls : serviceDecls serviceDecl { 924 if $2 != nil { 925 $$ = append($1, $2) 926 } else { 927 $$ = $1 928 } 929 } 930 | serviceDecl { 931 if $1 != nil { 932 $$ = []ast.ServiceElement{$1} 933 } else { 934 $$ = nil 935 } 936 } 937 | { 938 $$ = nil 939 } 940 941 // NB: doc suggests support for "stream" declaration, separate from "rpc", but 942 // it does not appear to be supported in protoc (doc is likely from grammar for 943 // Google-internal version of protoc, with support for streaming stubby) 944 serviceDecl : option { 945 $$ = $1 946 } 947 | rpc { 948 $$ = $1 949 } 950 | ';' { 951 $$ = ast.NewEmptyDeclNode($1) 952 } 953 | error ';' { 954 $$ = nil 955 } 956 | error { 957 $$ = nil 958 } 959 960 rpc : _RPC name rpcType _RETURNS rpcType ';' { 961 $$ = ast.NewRPCNode($1.ToKeyword(), $2, $3, $4.ToKeyword(), $5, $6) 962 } 963 | _RPC name rpcType _RETURNS rpcType '{' rpcDecls '}' { 964 $$ = ast.NewRPCNodeWithBody($1.ToKeyword(), $2, $3, $4.ToKeyword(), $5, $6, $7, $8) 965 } 966 967 rpcType : '(' _STREAM typeIdent ')' { 968 $$ = ast.NewRPCTypeNode($1, $2.ToKeyword(), $3, $4) 969 } 970 | '(' typeIdent ')' { 971 $$ = ast.NewRPCTypeNode($1, nil, $2, $3) 972 } 973 974 rpcDecls : rpcDecls rpcDecl { 975 if $2 != nil { 976 $$ = append($1, $2) 977 } else { 978 $$ = $1 979 } 980 } 981 | rpcDecl { 982 if $1 != nil { 983 $$ = []ast.RPCElement{$1} 984 } else { 985 $$ = nil 986 } 987 } 988 | { 989 $$ = nil 990 } 991 992 rpcDecl : option { 993 $$ = $1 994 } 995 | ';' { 996 $$ = ast.NewEmptyDeclNode($1) 997 } 998 | error ';' { 999 $$ = nil 1000 } 1001 | error { 1002 $$ = nil 1003 } 1004 1005 // excludes message, enum, oneof, extensions, reserved, extend, 1006 // option, optional, required, and repeated 1007 msgElementName : _NAME 1008 | _SYNTAX 1009 | _IMPORT 1010 | _WEAK 1011 | _PUBLIC 1012 | _PACKAGE 1013 | _TRUE 1014 | _FALSE 1015 | _INF 1016 | _NAN 1017 | _DOUBLE 1018 | _FLOAT 1019 | _INT32 1020 | _INT64 1021 | _UINT32 1022 | _UINT64 1023 | _SINT32 1024 | _SINT64 1025 | _FIXED32 1026 | _FIXED64 1027 | _SFIXED32 1028 | _SFIXED64 1029 | _BOOL 1030 | _STRING 1031 | _BYTES 1032 | _GROUP 1033 | _MAP 1034 | _TO 1035 | _MAX 1036 | _SERVICE 1037 | _RPC 1038 | _STREAM 1039 | _RETURNS 1040 1041 // excludes optional, required, and repeated 1042 extElementName : _NAME 1043 | _SYNTAX 1044 | _IMPORT 1045 | _WEAK 1046 | _PUBLIC 1047 | _PACKAGE 1048 | _OPTION 1049 | _TRUE 1050 | _FALSE 1051 | _INF 1052 | _NAN 1053 | _DOUBLE 1054 | _FLOAT 1055 | _INT32 1056 | _INT64 1057 | _UINT32 1058 | _UINT64 1059 | _SINT32 1060 | _SINT64 1061 | _FIXED32 1062 | _FIXED64 1063 | _SFIXED32 1064 | _SFIXED64 1065 | _BOOL 1066 | _STRING 1067 | _BYTES 1068 | _GROUP 1069 | _ONEOF 1070 | _MAP 1071 | _EXTENSIONS 1072 | _TO 1073 | _MAX 1074 | _RESERVED 1075 | _ENUM 1076 | _MESSAGE 1077 | _EXTEND 1078 | _SERVICE 1079 | _RPC 1080 | _STREAM 1081 | _RETURNS 1082 1083 // excludes reserved, option 1084 enumElementName : _NAME 1085 | _SYNTAX 1086 | _IMPORT 1087 | _WEAK 1088 | _PUBLIC 1089 | _PACKAGE 1090 | _TRUE 1091 | _FALSE 1092 | _INF 1093 | _NAN 1094 | _REPEATED 1095 | _OPTIONAL 1096 | _REQUIRED 1097 | _DOUBLE 1098 | _FLOAT 1099 | _INT32 1100 | _INT64 1101 | _UINT32 1102 | _UINT64 1103 | _SINT32 1104 | _SINT64 1105 | _FIXED32 1106 | _FIXED64 1107 | _SFIXED32 1108 | _SFIXED64 1109 | _BOOL 1110 | _STRING 1111 | _BYTES 1112 | _GROUP 1113 | _ONEOF 1114 | _MAP 1115 | _EXTENSIONS 1116 | _TO 1117 | _MAX 1118 | _ENUM 1119 | _MESSAGE 1120 | _EXTEND 1121 | _SERVICE 1122 | _RPC 1123 | _STREAM 1124 | _RETURNS 1125 1126 // excludes option, optional, required, and repeated 1127 oneofElementName : _NAME 1128 | _SYNTAX 1129 | _IMPORT 1130 | _WEAK 1131 | _PUBLIC 1132 | _PACKAGE 1133 | _TRUE 1134 | _FALSE 1135 | _INF 1136 | _NAN 1137 | _DOUBLE 1138 | _FLOAT 1139 | _INT32 1140 | _INT64 1141 | _UINT32 1142 | _UINT64 1143 | _SINT32 1144 | _SINT64 1145 | _FIXED32 1146 | _FIXED64 1147 | _SFIXED32 1148 | _SFIXED64 1149 | _BOOL 1150 | _STRING 1151 | _BYTES 1152 | _GROUP 1153 | _ONEOF 1154 | _MAP 1155 | _EXTENSIONS 1156 | _TO 1157 | _MAX 1158 | _RESERVED 1159 | _ENUM 1160 | _MESSAGE 1161 | _EXTEND 1162 | _SERVICE 1163 | _RPC 1164 | _STREAM 1165 | _RETURNS 1166 1167 name : _NAME 1168 | _SYNTAX 1169 | _IMPORT 1170 | _WEAK 1171 | _PUBLIC 1172 | _PACKAGE 1173 | _OPTION 1174 | _TRUE 1175 | _FALSE 1176 | _INF 1177 | _NAN 1178 | _REPEATED 1179 | _OPTIONAL 1180 | _REQUIRED 1181 | _DOUBLE 1182 | _FLOAT 1183 | _INT32 1184 | _INT64 1185 | _UINT32 1186 | _UINT64 1187 | _SINT32 1188 | _SINT64 1189 | _FIXED32 1190 | _FIXED64 1191 | _SFIXED32 1192 | _SFIXED64 1193 | _BOOL 1194 | _STRING 1195 | _BYTES 1196 | _GROUP 1197 | _ONEOF 1198 | _MAP 1199 | _EXTENSIONS 1200 | _TO 1201 | _MAX 1202 | _RESERVED 1203 | _ENUM 1204 | _MESSAGE 1205 | _EXTEND 1206 | _SERVICE 1207 | _RPC 1208 | _STREAM 1209 | _RETURNS 1210 1211 %%