|
|
1.1 ! root 1: .so ../ADM/mac ! 2: .XX 22 359 "Yacc: A Parser Generator" ! 3: .\".nr PD 1u \" bwk: little bit of paddability ! 4: .\".nr PI 2n ! 5: .rn SH sH ! 6: .fp 9 CB CW ! 7: .de SH ! 8: .SP 1.5 ! 9: .sH ! 10: \\$1. \\$2 ! 11: .PP ! 12: .nr H5 0 ! 13: .nr H4 0 ! 14: .nr H3 0 ! 15: .nr H2 0 ! 16: .nr H1 \\$1 ! 17: .. ! 18: .de SS ! 19: .NH 2 ! 20: \\$1 ! 21: .PP ! 22: .. ! 23: .de CB ! 24: .nr Ft \\n(.f ! 25: \&\\$3\&\\f(CB\\$1\&\\f\\n(Ft\\$2 ! 26: .. ! 27: .de Q{ ! 28: .in +20p ! 29: .X{ \\$1 ! 30: .. ! 31: .de P{ ! 32: .Q{ \\$1 ! 33: .tr _\(ru ! 34: .ft CB ! 35: .lg 0 ! 36: .. ! 37: .de Q} ! 38: .X} \\$1 ! 39: .in -20p ! 40: .. ! 41: .de P} ! 42: .lg ! 43: .Q} \\$1 ! 44: .. ! 45: .de X{ ! 46: .KS ! 47: .lg 0 ! 48: .ie \\n(.$ .SP \\$1 ! 49: .el .SP .5 ! 50: .nf ! 51: .ft 1 ! 52: .nr t 20p ! 53: .ta \\ntu +\\ntu +\\ntu +\\ntu +\\ntu +\\ntu +\\ntu +\\ntu +\\ntu +\\ntu +\\ntu +\\ntu +\\ntu +\\ntu +\\ntu ! 54: .. ! 55: .de X} ! 56: .ft 1 ! 57: .fi ! 58: .lg ! 59: .ie \\n(.$ .SP \\$1 ! 60: .el .SP .5 ! 61: .KE ! 62: .. ! 63: .de FI ! 64: .LP ! 65: .DS B ! 66: .fi ! 67: .nr PS 9 ! 68: .ps 9 ! 69: \\f3Figure \\$1\\$2.\\f1 ! 70: .. ! 71: .\" EF - end figure ! 72: .de EF ! 73: .DE ! 74: .fi ! 75: .nr PS 10 ! 76: .ps 10 ! 77: .if \\n(.$ .SP \\$1 ! 78: .if !\\n(.$ .SP ! 79: .LP ! 80: .. ! 81: .PS ! 82: arrowht = .08; arrowwid = .04 # default values are .1 and .05 ! 83: vs = 1/6 # 1/6 = 12p; for vertical distances ! 84: pagewid = 6; fillval = .98 ! 85: ! 86: # ln -- line to $1, $2 chop elliptically ! 87: # chopw and choph are the chop ellipse width and height ! 88: define ln % ! 89: { [ ! 90: x = $1*hu; y = $2*vu ! 91: xsq = x*x ! 92: rsq = xsq + y*y; r = sqrt(rsq); ! 93: asq = chopw*chopw/4; ! 94: bsq = choph*choph/4 ! 95: esq = (asq - bsq)/asq ! 96: p = sqrt(bsq/(1-esq*(xsq/rsq)))/r; ! 97: ! 98: O: "" ! 99: B: O + p*x, p*y ! 100: E: O + (1-p)*x, (1-p)*y ! 101: P: O + x,y ! 102: line $3 from B to E ! 103: ] with .O at Here ! 104: } ! 105: move to Here + $1*hu, $2*vu ! 106: % ! 107: # usage: adirection([e|n|w|s], [right|up|...], [1|0|1|0], Object) ! 108: define adirection % ! 109: axdir = $3 ! 110: move to $4 ! 111: $2 ! 112: % ! 113: define aright % adirection(e, right, 1, $1) % ! 114: define aleft % adirection(w, left, 1, $1) % ! 115: define anup % adirection(n, up, 0, $1) % ! 116: define adown % adirection(s, down, 0, $1) % ! 117: define anell % ! 118: ax = $1.x - Here.x; ay = $1.y - Here.y ! 119: Anell: Here + ax,ay ! 120: if axdir then| ! 121: line $3 from Here to Here + ax,0 chop 0 chop arcrad ! 122: if ax*ay > 0 then@ arc @else@ arc cw @ ! 123: axdir = 0 ! 124: |else| ! 125: line $3 from Here to Here + 0,ay chop 0 chop arcrad ! 126: if ax*ay < 0 then@ arc @else@ arc cw @ ! 127: axdir = 1 ! 128: | ! 129: line $2 to Anell ! 130: % axdir = 1 ! 131: .PE ! 132: .fp 8 SS S ! 133: .EQ ! 134: define Small % size 7 "$1" % ! 135: define f2 % "\&" font 2 "$1" % ! 136: define cdot % "\s7\f8\N'183'\fP\s0" % ! 137: define => % "\v'-.15m'\f8\N'222'\fP\v'.15m'" % ! 138: define C++ % "\f1C\h'-.14m'+\h'-.18'+\fP" % ! 139: define <! % "\f8\N'225'\fP" % ! 140: define >! % "\f8\N'241'\fP" % ! 141: delim $$ ! 142: .EN ! 143: .ND "July 1, 1989" ! 144: .TL ! 145: Yacc: A Parser Generator\(dg ! 146: .AU ! 147: Stephen C. Johnson ! 148: Ravi Sethi ! 149: .AI ! 150: .MH ! 151: .AB ! 152: Since the early 1970s, Yacc has been used to implement ! 153: hundreds of languages, big and small. ! 154: Its applications range from small desk calculators ! 155: to medium-sized preprocessors for typesetting ! 156: to large compiler front ends for complete programming languages. ! 157: .PP ! 158: A Yacc specification is based on a collection of grammar rules ! 159: describing the syntax of a language; Yacc turns the ! 160: specification into a syntax analyzer. ! 161: A pure syntax analyzer merely checks whether or not an input string ! 162: conforms to the syntax of the language. ! 163: .PP ! 164: We can go beyond pure syntax analysis by attaching code in C ! 165: or $C++$ to ! 166: a grammar rule; such code is called an action, and is executed ! 167: whenever the rule is applied during syntax analysis. ! 168: Thus, a desk calculator might use actions to evaluate an expression, ! 169: and a compiler front end might use actions to ! 170: emit intermediate code. ! 171: .PP ! 172: Yacc allows us to build parsers from LALR(1) grammars ! 173: without necessarily learning the underlying theory. ! 174: .AE ! 175: .@tag SH _SH1_ ! 176: .FS ! 177: \(dg Prepared by R. Sethi from\&|reference(v7yacc)\&. ! 178: S. C. Johnson is presently with Ardent Computer, ! 179: 880 West Maude Ave., ! 180: Sunnyvale, California 94086. ! 181: .FE ! 182: .SH _SH1_ "Introduction" ! 183: .LP ! 184: Yacc is a tool for building syntax analyzers, also known as ! 185: .I parsers . ! 186: This section introduces the basic features of Yacc. ! 187: We review grammars, build a pure parser ! 188: for real numbers, and then augment the parser to evaluate ! 189: numbers during parsing. ! 190: The language of real numbers is a toy; ! 191: realistic examples appear in Section _SH2_. ! 192: .PP ! 193: Uppercase letters are distinct from lowercase letters ! 194: in Yacc specifications. ! 195: Thus, ! 196: .CW digit ! 197: and ! 198: .CW DIGIT ! 199: are distinct names. ! 200: The font of a name is chosen purely for readability, so ! 201: .CW fraction , ! 202: and $fraction$ (within diagrams) ! 203: refer to the same name. ! 204: .SS "Further Reading" ! 205: Yacc is designed to handle a single but significant part ! 206: of the total job of building a translator or interpreter ! 207: for a language. ! 208: The remaining parts of the job must be implemented ! 209: in a host programming language, ! 210: presumed to be C|reference(Kernighan Ritchie 1988) or ! 211: $C++$|reference(Stroustrup book 1986). ! 212: .PP ! 213: Another progam generator, designed to work in harmony with Yacc, ! 214: is Lex|reference(latest lex), a tool developed for ! 215: building lexical analyzers. ! 216: Lex can be easily used to produce quite complicated lexical analyzers, ! 217: but there remain some languages (such as Fortran) that do not ! 218: fit any theoretical framework, and whose lexical analyzers ! 219: must be crafted by hand. ! 220: .PP ! 221: Kernighan and Pike illustrate program development ! 222: using Yacc and Lex by gradually extending an expression evaluator ! 223: into an interpreter for a language comparable to Basic|reference(Kernighan Pike). ! 224: Schreiner and Friedman conduct a book-length case ! 225: study of how to create a compiler using Yacc and Lex|reference(Schreiner Friedman). ! 226: .PP ! 227: Textbooks on compilers often provide more information on the behavior and ! 228: construction of parsers than will be covered here; see for example ! 229: \&|reference(Aho Sethi Ullman 1986)\&. ! 230: The algorithms underlying Yacc are also discussed in the survey ! 231: of LR parsing by ! 232: \&|reference(Aho Johnson surveys)\&. ! 233: A feature that sets Yacc apart \(em its ability to build fast compact ! 234: LR parsers from ambiguous grammars \(em is based on the theory ! 235: developed by ! 236: \&|reference(Aho Johnson Ullman ambiguous)\&. ! 237: .PP ! 238: Among the earliest applications of Yacc are ! 239: EQN|reference(Kernighan Cherry 1975), a language for typesetting mathematics, and ! 240: PCC, the Portable C Compiler|reference(Johnson portable acm). ! 241: .SS "Grammars, Reviewed" ! 242: The ! 243: .I syntax ! 244: of a language imposes a hierarchical structure, ! 245: called a ! 246: .I "parse tree" , ! 247: on strings in the language. ! 248: The following is a parse tree for the string ! 249: .CW 3.14 ! 250: in a language of real numbers: ! 251: .KS ! 252: .ps 9 ! 253: .ft CB ! 254: .PS ! 255: [ ! 256: hu = .5; vu = 1.5*vs; choph = vs; chopw = .7 ! 257: boxht = vs; boxwid = .8*vs ! 258: ! 259: "$realNumber$" ! 260: { ! 261: ln(-1,-1); "$integerPart$" ! 262: ln( 0,-1); "$digit$" ! 263: ln( 0,-2); "3" ! 264: }{ ! 265: ln( 0,-4); "." ! 266: }{ ! 267: ln( 1.5,-1); "$fraction$" ! 268: { ! 269: ln(-0.5,-1); "$digit$" ! 270: ln( 0,-2); "1" ! 271: }{ ! 272: ln( 0.5,-1); "$fraction$" ! 273: ln( 0,-1); "$digit$" ! 274: ln( 0,-1); "4" ! 275: } ! 276: } ! 277: ] ! 278: .PE ! 279: .KE ! 280: .PP ! 281: The leaves at the bottom of a parse tree are labeled with ! 282: .I terminals ! 283: or ! 284: .I tokens ; ! 285: tokens represent themselves. ! 286: By contrast, the other nodes of a parse tree are labeled with ! 287: .I nonterminals . ! 288: Each node in the parse tree is based on a rule ! 289: that defines a nonterminal in terms of a sequence of ! 290: terminals and nonterminals. ! 291: Such rules are called ! 292: .I productions . ! 293: The root of the preceding parse tree is based on the ! 294: following informally stated production: ! 295: .Q{ ! 296: A real number consists of an integer part, a point, and a fraction. ! 297: .Q} ! 298: This production is written as follows in the notation accepted by Yacc: ! 299: .P{ ! 300: realNumber : integerPart '.' fraction ! 301: ; ! 302: .P} ! 303: .PP ! 304: Together, the tokens, the nonterminals, the productions, and a ! 305: distinguished nonterminal, called the ! 306: .I "start symbol" , ! 307: constitute a ! 308: .I grammar ! 309: for a language. ! 310: Both tokens and nonterminals can be referred to as ! 311: .I "grammar symbols" , ! 312: or simply ! 313: .I symbols . ! 314: .SS "Grammars in Yacc Specifications" ! 315: A Yacc specification has three sections for ! 316: optional declarations, productions, and optional user-supplied programs. ! 317: The productions are the heart of a specification; they are ! 318: darker for emphasis in Figure _FI2_. ! 319: The sections are separated by ! 320: double percent ! 321: .CW %% ! 322: marks \(em the percent symbol ! 323: is generally used by Yacc as an escape character. ! 324: If the programs section is omitted, the second ! 325: .CW %% ! 326: mark can be omitted as well. ! 327: .KF bottom ! 328: .ps 9 ! 329: .nf ! 330: \s5\l'\n(LLu\&\(ul'\s0 ! 331: .fi ! 332: .PS ! 333: [ ! 334: define text % [ ! 335: B: box ht vs wid pagewid invis ! 336: $1 ljust at B.w + 20/72,0 ! 337: ] % ! 338: down ! 339: .ft CW ! 340: text("%start lines") ! 341: text("%%") ! 342: .ft CB ! 343: text("lines : /* empty */") ! 344: text(" | lines realNumber '\en'") ! 345: text(" ;") ! 346: text("realNumber : integerPart '.' fraction") ! 347: text(" ;") ! 348: text("integerPart : digit") ! 349: text(" | integerPart digit") ! 350: text(" ;") ! 351: text("fraction : digit") ! 352: text(" | digit fraction") ! 353: text(" ;") ! 354: text("digit : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'") ! 355: text(" ;") ! 356: .ft CW ! 357: text("%%") ! 358: text("#include <stdio.h>") ! 359: text("int yylex() { return getchar(); }") ! 360: text("int main() { return yyparse(); }") ! 361: text("void yyerror(s) char *s; { fprintf(stderr, \"%s\en\", s); }") ! 362: ] ! 363: .PE ! 364: .@tag FI _FI2_ ! 365: .FI _FI2_ ! 366: A complete Yacc specification for sequences of real numbers, one per line. ! 367: .EF 0 ! 368: .nf ! 369: \s5\l'\n(LLu\&\(ul'\s0 ! 370: .fi ! 371: .SP ! 372: .KE ! 373: .PP ! 374: Blanks, tabs, and newlines are ignored. ! 375: Comments can appear wherever a name can; they are enclosed ! 376: between ! 377: .CW /* ! 378: and ! 379: .CW */ , ! 380: as in C. ! 381: .PP ! 382: It is possible, and desirable, for the start symbol of a grammar ! 383: to be declared explicitly, using the ! 384: .CW %start ! 385: keyword, as in ! 386: .P{ ! 387: %start lines ! 388: .P} ! 389: Otherwise, the start symbol is taken from the first production in the ! 390: specification. ! 391: .PP ! 392: A name in the production section is presumed to represent a nonterminal ! 393: unless it is explicitly declared to represent a token. ! 394: There are no token declarations in Figure _FI2_; ! 395: later in this section, ! 396: .CW DIGIT ! 397: will be declared to be a token by writing ! 398: .P{ ! 399: %token DIGIT ! 400: .P} ! 401: .PP ! 402: Single-character tokens need not be declared; a ! 403: .I literal ! 404: is a character enclosed in single quotes. ! 405: As in C, the backslash ! 406: .CW \e ! 407: is an escape character within literals, and the following C escapes are ! 408: recognized: ! 409: .ft CB ! 410: .TS ! 411: lw4 0 l l. ! 412: '\en' \f1newline\fP ! 413: '\er' \f1return\fP ! 414: '\e'' \f1single quote \fP'\f1\fP ! 415: '\et' \f1tab\fP ! 416: '\eb' \f1backspace\fP ! 417: '\ef' \f1form feed\fP ! 418: '\exxx' \f1``\fPxxx\f1'' in octal ! 419: .TE ! 420: For technical reasons, the ! 421: .CW NUL ! 422: character, ! 423: .CW '\e0' ! 424: or ! 425: .CW 0 , ! 426: should never be used in productions. ! 427: .PP ! 428: A production ! 429: .P{ ! 430: realNumber : integerPart '.' fraction ! 431: ; ! 432: .P} ! 433: defines a nonterminal, called its ! 434: .I "left side" , ! 435: in terms of a sequence of grammar symbols, called its ! 436: .I "right side" . ! 437: A colon separates the two sides, and a semicolon marks the end ! 438: of the production. ! 439: The left side of this production is ! 440: .CW realNumber . ! 441: Its right side consists of ! 442: .CW integerPart , ! 443: the literal ! 444: .CW '.' , ! 445: and ! 446: .CW fraction . ! 447: .PP ! 448: The right side of a production can be empty, as in the following ! 449: production with no symbols between the colon and the ! 450: terminating semicolon: ! 451: .P{ ! 452: lines : ; ! 453: .P} ! 454: .PP ! 455: Productions with the same left side can be combined, and written with ! 456: a vertical bar separating the right sides. ! 457: The productions ! 458: .P{ ! 459: integerPart : digit ! 460: ; ! 461: integerPart : integerPart digit ! 462: ; ! 463: .P} ! 464: can be rewritten equivalently as ! 465: .P{ ! 466: integerPart : digit ! 467: | integerPart digit ! 468: ; ! 469: .P} ! 470: In words, an integer part is either a single digit or a ! 471: (smaller) integer part followed by a digit. ! 472: Thus, ! 473: an integer part consists of ! 474: a string of one or more digits. ! 475: .PP ! 476: A fraction also consists of a string of one or more digits; ! 477: however, the productions for ! 478: .CW fraction ! 479: impose a different hierarchical ! 480: structure on strings of digits. ! 481: The productions are ! 482: .P{ ! 483: fraction : digit ! 484: | digit fraction ! 485: ; ! 486: .P} ! 487: Note how a tree for ! 488: .CW integerPart ! 489: grows down to the left, whereas a tree for ! 490: .CW fraction ! 491: grows down to the right: ! 492: .KS ! 493: .ps 9 ! 494: .ft CB ! 495: .PS ! 496: [ ! 497: hu = .5; vu = 1.5*vs; choph = vs; chopw = .7 ! 498: boxht = vs ! 499: ! 500: IntegerPart:\ ! 501: [ ! 502: "$integerPart$" ! 503: { ! 504: ln( 1,-1); "$digit$" ! 505: ln( 0,-1); "3" ! 506: } ! 507: ln(-1,-1); "$integerPart$" ! 508: { ! 509: ln( 1,-1); "$digit$" ! 510: ln( 0,-1); "2" ! 511: } ! 512: ln(-1,-1); "$integerPart$" ! 513: { ! 514: ln( 0,-1); "$digit$" ! 515: ln( 0,-1); "1" ! 516: }{ ! 517: box invis wid .8 at Here ! 518: } ! 519: ] ! 520: Fraction:\ ! 521: [ ! 522: "$fraction$" ! 523: { ! 524: ln(-1,-1); "$digit$" ! 525: ln( 0,-1); "7" ! 526: } ! 527: ln( 1,-1); "$fraction$" ! 528: { ! 529: ln(-1,-1); "$digit$" ! 530: ln( 0,-1); "8" ! 531: } ! 532: ln( 1,-1); "$fraction$" ! 533: { ! 534: ln( 0,-1); "$digit$" ! 535: ln( 0,-1); "9" ! 536: }{ ! 537: box invis wid .6 at Here ! 538: } ! 539: ] with .e at IntegerPart.w + pagewid-2*20/72,0 ! 540: ] ! 541: .PE ! 542: .KE ! 543: .LP ! 544: The different hierarchical structures imposed by ! 545: .CW integerPart ! 546: and ! 547: .CW fraction ! 548: on strings of digits facilitate the evaluation of real numbers, ! 549: as we shall see later in this section. ! 550: .SS "Using Yacc" ! 551: Parsers generated by Yacc need to be supplemented ! 552: before a self-contained application is built. ! 553: Only four lines are devoted to such supplementary ! 554: code at the end of Figure _FI2_. ! 555: In other words, ! 556: Yacc confines itself to generating fast parsers, leaving ! 557: us with both the control and responsibility ! 558: for all other aspects of an application. ! 559: .PP ! 560: The use of Yacc is illustrated in Figure _FI3_. ! 561: The code of a Yacc-generated parser is a function, ! 562: .CW yyparse , ! 563: which returns 0 ! 564: if the entire input is parsed successfully; ! 565: otherwise, it returns 1. ! 566: The function ! 567: .CW yyparse ! 568: gets tokens by repeatedly calling ! 569: .CW yylex , ! 570: a lexical analyzer. ! 571: .KF bottom ! 572: .nf ! 573: \s5\l'\n(LLu\&\(ul'\s0 ! 574: .fi ! 575: .nr PS 9 ! 576: .ps 9 ! 577: .vs 11 ! 578: .PS ! 579: [ ! 580: fillval = 1 ! 581: boxht = 2.5*vs; boxwid = .6 ! 582: lineht = vs; linewid = .25 ! 583: ! 584: right ! 585: box invis "character" "stream" wid .7 ! 586: line -> ! 587: box "lexical" "analyzer" fill ! 588: line -> ! 589: box invis "token" "stream" ! 590: line -> ! 591: box "syntax" "analyzer" fill ! 592: { ! 593: move to last box.n ! 594: up ! 595: line <- ! 596: box "C" "compiler" ! 597: line <- ! 598: box "Yacc" fill ! 599: line <- ! 600: box invis ht 1.5*vs "grammar" ! 601: } ! 602: line -> ! 603: box invis "optional" "output" ! 604: ] ! 605: .PE ! 606: .@tag FI _FI3_ ! 607: .FI _FI3_ ! 608: Yacc handles the syntax analysis part of an application. ! 609: .EF 0 ! 610: .nf ! 611: \s5\l'\n(LLu\&\(ul'\s0 ! 612: .fi ! 613: .SP ! 614: .KE ! 615: .PP ! 616: A ! 617: .I "lexical analyzer" ! 618: reads input characters and returns tokens. ! 619: The simplest lexical analyzer returns each individual character ! 620: as a token; it is defined by ! 621: .P{ ! 622: int yylex() { return getchar(); } ! 623: .P} ! 624: .PP ! 625: Execution of a C program begins in a function called ! 626: .CW main , ! 627: so ! 628: .CW main ! 629: must call ! 630: .CW yyparse. ! 631: The code for ! 632: .CW main ! 633: in Figure _FI2_ ! 634: .P{ ! 635: int main() { return yyparse(); } ! 636: .P} ! 637: simply returns the result obtained from ! 638: .CW yyparse ; ! 639: more generally, ! 640: .CW main ! 641: might read command-line arguments and options ! 642: before calling ! 643: .CW yyparse . ! 644: .PP ! 645: If a syntax error occurs during parsing, ! 646: .CW yyparse ! 647: calls a user-supplied function ! 648: .CW yyerror ! 649: with a terse message, usually ! 650: .CW "syntax error" .'' `` ! 651: The following implementation of ! 652: .CW yyerror ! 653: prints the message : ! 654: .P{ ! 655: void yyerror(s) char *s; { fprintf(stderr, "%s\en", s); } ! 656: .P} ! 657: Parsing terminates when an error is detected unless ``error productions'' ! 658: are used as described in Section _SH5_. ! 659: .PP ! 660: We have now examined all the pieces of the specification in ! 661: Figure _FI2_ except ! 662: .P{ ! 663: #include <stdio.h> ! 664: .P} ! 665: which provides access to input/output facilities from a ! 666: standard library. ! 667: .PP ! 668: When Yacc is applied to a specification, the output ! 669: is a file of C programs, called ! 670: .CW y.tab.c ! 671: on most systems ! 672: (the name might differ due to local file-system conventions). ! 673: Suppose that the specification in Figure _FI2_ appears in a file ! 674: .CW real.y . ! 675: A program for reading a sequence of real numbers can then be ! 676: constructed by the following ! 677: .UX ! 678: system commands: ! 679: .ft CB ! 680: .TS ! 681: lw4 0 l8 l. ! 682: yacc real.y \f2generates C code into file \&\fPy.tab.c ! 683: cc y.tab.c \f2compiles executable program into file \&\fPa.out ! 684: .TE ! 685: .LP ! 686: The compiled program ! 687: .CW a.out ! 688: silently reads real numbers, one per line, until the end of the input ! 689: is reached, or until a syntax error occurs. ! 690: The specification will now be extended to evaluate real numbers ! 691: as they are read. ! 692: .EQ ! 693: delim off ! 694: .EN ! 695: .SS "Actions and Attributes" ! 696: An action attached to a production is ! 697: executed each time the production is applied during parsing. ! 698: An ! 699: .I action ! 700: consists of one or more C statements, enclosed in curly braces ! 701: .CW { ! 702: and ! 703: .CW } . ! 704: Within an action, pseudo-variables starting with ! 705: .CW $ ! 706: signs refer to values associated with the symbols in the production. ! 707: The pseudo-variable for the left side is ! 708: .CW $$ ; ! 709: the pseudo-variable for a symbol on the right side ! 710: is formed by prefixing a ! 711: .CW $ ! 712: sign to its name or to its position. ! 713: .PP ! 714: The action in ! 715: .P{ ! 716: realNumber : integerPart fraction { $$ = $integerPart + $fraction; } ; ! 717: .P} ! 718: is the single statement ! 719: .P{ ! 720: $$ = $integerPart + $fraction; ! 721: .P} ! 722: .EQ ! 723: delim @@ ! 724: .EN ! 725: It defines the value associated with the left side to be the sum of the ! 726: values associated with the two symbols on the right side.@"" sup _FS#_@ ! 727: .FS ! 728: .@tag FS _FS#_ ! 729: @"" sup _FS#_@ ! 730: When the same symbol @s@ appears several times on the right side, ! 731: its pseudo-variable can be written as ! 732: .CW $@s@#1 , ! 733: .CW $@s@#2 , ! 734: .CW $@s@#3 . ! 735: .FE ! 736: Using pseudo-variables formed from positions on the right side, instead of ! 737: names, the action can be rewritten equivalently as ! 738: .EQ ! 739: delim off ! 740: .EN ! 741: .P{ ! 742: realNumber : integerPart fraction { $$ = $1 + $2; } ; ! 743: .P} ! 744: This production and action are from the complete specification ! 745: in Figure _FI2A_. ! 746: .PP ! 747: Earlier versions of Yacc support only positional pseudo-variables ! 748: like ! 749: .CW $1 ! 750: and ! 751: .CW $2 . ! 752: .PP ! 753: The type of the values associated with grammar symbols is given by ! 754: .CW YYSTYPE , ! 755: defined to be ! 756: .CW double ! 757: in Figure _FI2A_. ! 758: The default type for ! 759: .CW YYSTYPE ! 760: is ! 761: .CW int . ! 762: Any C code in the declarations section must be enclosed between ! 763: .CW %{ ! 764: and ! 765: .CW %} . ! 766: See Section _SH6_ for how to associate different types of values with ! 767: different grammar symbols. ! 768: .KF ! 769: .ps 9 ! 770: .nf ! 771: \s5\l'\n(LLu\&\(ul'\s0 ! 772: .fi ! 773: .PS ! 774: [ ! 775: define text % [ ! 776: B: box ht vs wid pagewid invis ! 777: $1 ljust at B.w + 20/72,0 ! 778: ] % ! 779: down ! 780: .ft CW ! 781: text("%token DIGIT") ! 782: text("%start lines") ! 783: text("%{") ! 784: text("#def\&ine YYSTYPE double") ! 785: text("%}") ! 786: text("%%") ! 787: .ft CB ! 788: text("lines : lines realNumber '\en'") ! 789: .ft CW ! 790: text(" { printf(\"%g\en\", $realNumber); }") ! 791: .ft CB ! 792: text(" | /* empty */") ! 793: text(" ;") ! 794: text("realNumber : integerPart '.' fraction") ! 795: .ft CW ! 796: text(" { $$ = $integerPart + $fraction; }") ! 797: .ft CB ! 798: text(" ;") ! 799: text("integerPart : DIGIT") ! 800: text(" | integerPart DIGIT") ! 801: .ft CW ! 802: text(" { $$ = $integerPart*10 + $DIGIT; }") ! 803: .ft CB ! 804: text(" ;") ! 805: text("fraction : DIGIT") ! 806: .ft CW ! 807: text(" { $$ = $DIGIT*0.1; }") ! 808: .ft CB ! 809: text(" | DIGIT fraction") ! 810: .ft CW ! 811: text(" { $$ = ($DIGIT + $fraction)*0.1; }") ! 812: .ft CB ! 813: text(" ;") ! 814: .ft CW ! 815: text("%%") ! 816: text("#include <stdio.h>") ! 817: text("#include <ctype.h>") ! 818: text("int yylex() {") ! 819: text(" int c;") ! 820: text(" c = getchar();") ! 821: text(" if( ! isdigit(c) ) return c;") ! 822: text(" yylval = c - '0';") ! 823: text(" return DIGIT;") ! 824: text("}") ! 825: text("int main() { return yyparse(); }") ! 826: text("void yyerror(s) char *s; { fprintf(stderr, \"%s\en\", s); }") ! 827: ] ! 828: .PE ! 829: .@tag FI _FI2A_ ! 830: .FI _FI2A_ ! 831: The actions in this Yacc specification evaluate real numbers during parsing. ! 832: .EF 0 ! 833: .nf ! 834: \s5\l'\n(LLu\&\(ul'\s0 ! 835: .fi ! 836: .SP ! 837: .KE ! 838: .PP ! 839: The tree in Figure _FI2C_ illustrates the evaluation of the real number ! 840: .CW 321.789 . ! 841: (The tree is technically not a parse tree because its root is not ! 842: for the start symbol ! 843: .CW lines , ! 844: and the nodes are labeled with values rather than grammar symbols.) ! 845: .KF ! 846: .EQ ! 847: delim $$ ! 848: .EN ! 849: .nf ! 850: \s5\l'\n(LLu\&\(ul'\s0 ! 851: .fi ! 852: .ps 9 ! 853: .ft CB ! 854: .PS ! 855: [ ! 856: define intp % { ! 857: "$f2($integerPart)^=^$1$" ! 858: } % ! 859: define frac % { ! 860: "$f2($fraction)^=^$1$" ! 861: } % ! 862: define DIGIT % { ! 863: "$Small($DIGIT)^=^$1$" ! 864: } % ! 865: ! 866: hu = .6; vu = 2.5*vs; choph = vs; chopw = .7 ! 867: boxht = vs ! 868: ! 869: "$f2($realNumber)^=^321.789$" ! 870: { ! 871: ln(-2,-1); intp(321) ! 872: { ! 873: ln( 1,-1); DIGIT(1) ! 874: } ! 875: ln(-1,-1); intp(32) ! 876: { ! 877: ln( 1,-1); DIGIT(2) ! 878: } ! 879: ln(-1,-1); intp(3) ! 880: { ! 881: ln( 0,-1); DIGIT(3) ! 882: }{ ! 883: box invis wid .85 at Here ! 884: } ! 885: }{ ! 886: ln( 2,-1); frac(0.789) ! 887: { ! 888: ln(-1,-1); DIGIT(7) ! 889: } ! 890: ln( 1,-1); frac(0.89) ! 891: { ! 892: ln(-1,-1); DIGIT(8) ! 893: } ! 894: ln( 1,-1); frac(0.9) ! 895: { ! 896: ln( 0,-1); DIGIT(9) ! 897: }{ ! 898: box invis wid .8 at Here ! 899: } ! 900: } ! 901: ] ! 902: .PE ! 903: .@tag FI _FI2C_ ! 904: .FI _FI2C_ ! 905: Attribute values during the evaluation of ! 906: .CB 321.789 . ! 907: .EF 0 ! 908: .nf ! 909: \s5\l'\n(LLu\&\(ul'\s0 ! 910: .fi ! 911: .SP ! 912: .EQ ! 913: delim off ! 914: .EN ! 915: .KE ! 916: .PP ! 917: A value associated with a node in a parse tree is called an ! 918: .I attribute . ! 919: For the moment, the attribute at a node will be defined solely in ! 920: terms of the attributes at the children of the node. ! 921: .PP ! 922: Attributes for tokens are defined by the lexical analyzer. ! 923: Conceptually, a lexical analyzer returns a pair, consisting ! 924: of a token and an associated attribute value. ! 925: For example, in Figure _FI2A_, ! 926: .CW DIGIT ! 927: is a token. ! 928: When the lexical analyzer reads the character ! 929: .CW 1 ! 930: it returns ! 931: .CW DIGIT ! 932: with attribute value 1, when it reads ! 933: .CW 2 ! 934: it returns ! 935: .CW DIGIT ! 936: with attribute value 2, and so on. ! 937: .PP ! 938: Specifically, the parser ! 939: .CW yyparse ! 940: expects the lexical analyzer ! 941: .CW yylex ! 942: to leave the attribute value in a global variable ! 943: .CW yylval . ! 944: The function ! 945: .CW yylex ! 946: in Figure _FI2A_ assigns a value to ! 947: .CW yylval ! 948: just before it returns the token ! 949: .CW DIGIT . ! 950: .PP ! 951: Starting in the bottom-left corner of Figure _FI2C_, ! 952: the lexical analyzer sets the attribute value 3 at the ! 953: leftmost leaf for the token ! 954: .CW DIGIT . ! 955: The parent of this leaf is based on the production and action ! 956: .P{ ! 957: integerPart : DIGIT { $$ = $1; } ; ! 958: .P} ! 959: This action is omitted in Figure _FI2A_ because, by default, ! 960: the parser sets the attribute of the left side to that of the ! 961: first symbol on the right side. ! 962: .PP ! 963: Working up the tree, the next node is based on ! 964: .P{ ! 965: integerPart : integerPart DIGIT { $$ = $integerPart + $DIGIT; } ; ! 966: .P} ! 967: .PP ! 968: The effect of the actions is perhaps easier to see at the nodes ! 969: for ! 970: .CW fraction . ! 971: At the only node based on ! 972: .P{ ! 973: fraction : DIGIT { $$ = $DIGIT*0.1; } ; ! 974: .P} ! 975: the value of ! 976: .CW $DIGIT ! 977: is 9 and the value of ! 978: .CW $fraction ! 979: is 0.9. ! 980: .PP ! 981: Since Yacc generates bottom-up parsers, bottom-up evaluation of ! 982: attribute values fits naturally with parsing. ! 983: Actions attached to productions are examined further in Section _SH2_; ! 984: their execution order becomes significant when ! 985: they do input/output, assign values to variables, call functions ! 986: with side effects, or otherwise affect the state of a computation. ! 987: .SS "A Style for Specifications" ! 988: Choose a style that makes the productions ! 989: visible through the morass of action code. ! 990: .SP .5 ! 991: .IP a. 4 ! 992: Use all capital letters for token names, all lower case letters for ! 993: nonterminal names. ! 994: This hint comes under the heading of ``knowing who to blame when ! 995: things go wrong.'' ! 996: .SP .25 ! 997: .IP b. ! 998: Put productions and actions on separate lines. ! 999: Either can then be changed independently. ! 1000: .SP .25 ! 1001: .IP c. ! 1002: Put all productions with the same left side together. ! 1003: Put the left side in only once, and let all ! 1004: following productions begin with a vertical bar. ! 1005: .SP .25 ! 1006: .IP d. ! 1007: Put a semicolon only after the last production with a given left side, ! 1008: and put the semicolon on a separate line. ! 1009: New productions can then be easily added. ! 1010: .SP .25 ! 1011: .IP e. ! 1012: Indent production bodies by one tab stop, and action bodies by two ! 1013: tab stops. ! 1014: .PP ! 1015: These style hints owe much to Brian Kernighan. ! 1016: The examples in this paper sometimes deviate from this style to conserve space. ! 1017: .EQ ! 1018: delim $$ ! 1019: .EN ! 1020: .@tag SH _SH2_ ! 1021: .SH _SH2_ "Evaluation And Translation Of Expressions" ! 1022: Both actions and productions must be considered ! 1023: when a Yacc specification is designed. ! 1024: Without actions, a parser would silently analyze input strings, ! 1025: complaining only if it detects an error. ! 1026: With suitable actions, a parser can become an evaluator or ! 1027: a translator. ! 1028: Typically, the desired actions ! 1029: influence the choice of productions. ! 1030: .PP ! 1031: For example, the actions for evaluating the integer and fractional ! 1032: parts of a real number motivate different productions for ! 1033: the sequences of digits ! 1034: represented by ! 1035: .CW integerPart ! 1036: and ! 1037: .CW fraction ! 1038: in Section _SH1_. ! 1039: In the integer part, the contribution of a digit depends on the ! 1040: number of digits to its right; the contribution of ! 1041: .CW 3 ! 1042: in ! 1043: .CW 321.789 ! 1044: is 300, where the number of zeros depends on the number of ! 1045: digits to its right. ! 1046: In the fractional part, however, the contribution of a digit ! 1047: depends on the number of digits to its left; the contribution ! 1048: of ! 1049: .CW 9 ! 1050: in ! 1051: .CW 321.789 ! 1052: is 0.009, where the number of zeros depends on the number of ! 1053: digits to its left. ! 1054: .PP ! 1055: Arithmetic expressions are a fertile source of examples for Yacc ! 1056: because the specifications of expression evaluators and translators are ! 1057: quite short and the ideas carry over to richer languages. ! 1058: This section begins with a specification for an ! 1059: expression evaluator. ! 1060: The evaluator benefits from Yacc's facilities for ! 1061: specifying the associativity and precedence of operators ! 1062: within expressions. ! 1063: The next example, a translator from infix into postfix notation, ! 1064: illustrates parsing order. ! 1065: .SS "Grammars for Expressions" ! 1066: Expressions are characterized by the operators within them; ! 1067: the choice of productions for expressions ! 1068: depends on the associativity and precedence of operators. ! 1069: .PP ! 1070: An operator ! 1071: .CW OP ! 1072: is ! 1073: .I "left associative" ! 1074: if an expression ! 1075: .P{ ! 1076: expr$"" sub 1$ OP expr$"" sub 2$ OP expr$"" sub 3$ ! 1077: .P} ! 1078: is evaluated as if it were parenthesized as ! 1079: .P{ ! 1080: (expr$"" sub 1$ OP expr$"" sub 2$) OP expr$"" sub 3$ ! 1081: .P} ! 1082: Similarly, the operator is ! 1083: .I "right associative" ! 1084: if the expression is evaluated as if it were parenthesized as ! 1085: .P{ ! 1086: expr$"" sub 1$ OP (expr$"" sub 2$ OP expr$"" sub 3$) ! 1087: .P} ! 1088: .PP ! 1089: An operator ! 1090: .CW OPA ! 1091: has ! 1092: .I "lower precedence" ! 1093: than an operator ! 1094: .CW OPB ! 1095: if the following equivalences hold (that is, the expressions to the ! 1096: left and right of the $==$ signs have the same values): ! 1097: .ft CB ! 1098: .TS ! 1099: lw4 0 r2 c2 l. ! 1100: expr$"" sub 1$ OPA expr$"" sub 2$ OPB expr$"" sub 3$ $==$ expr$"" sub 1$ OPA (expr$"" sub 2$ OPB expr$"" sub 3$) ! 1101: expr$"" sub 1$ OPB expr$"" sub 2$ OPA expr$"" sub 3$ $==$ (expr$"" sub 1$ OPB expr$"" sub 2$) OPA expr$"" sub 3$ ! 1102: .TE ! 1103: .PP ! 1104: The traditional grammar for arithmetic expressions uses three nonterminals ! 1105: .CW expr , ! 1106: .CW term , ! 1107: and ! 1108: .CW factor , ! 1109: where ! 1110: .CW expr ! 1111: represents an expression and ! 1112: .CW term ! 1113: and ! 1114: .CW factor ! 1115: represent subexpressions: ! 1116: .P{ ! 1117: %token NUMBER VAR ! 1118: %% ! 1119: expr : expr '+' term | expr '-' term | term ! 1120: ; ! 1121: term : term '*' factor | term '/' factor | factor ! 1122: ; ! 1123: factor : NUMBER | VAR | '(' expr ')' ! 1124: ; ! 1125: .P} ! 1126: In words, an expression is a sequence of terms separated ! 1127: by ! 1128: .CW + ! 1129: or ! 1130: .CW - ! 1131: signs. ! 1132: A term is a sequence of factors separated by ! 1133: .CW * ! 1134: or ! 1135: .CW / ! 1136: signs. ! 1137: Thus, ! 1138: .P{ ! 1139: b*b - 4*a*c ! 1140: .P} ! 1141: is an expression containing two terms ! 1142: .CW b*b ! 1143: and ! 1144: .CW 4*a*c . ! 1145: The term ! 1146: .CW 4*a*c ! 1147: has three factors ! 1148: .CW 4 , ! 1149: .CW a , ! 1150: and ! 1151: .CW c . ! 1152: A factor is either a number, a variable, or a parenthesized expression. ! 1153: .PP ! 1154: Ths grammar for expressions ! 1155: dates back to 1960 when Backus\&|reference(Backus 1960 %no_cite)\& ! 1156: introduced BNF, a notation for writing grammars. ! 1157: .PP ! 1158: A desk calculator can be based on this grammar ! 1159: by adding actions, as in ! 1160: .EQ ! 1161: delim off ! 1162: .EN ! 1163: .P{ ! 1164: expr : expr '-' term { $$ = $expr - $term; } ! 1165: .P} ! 1166: .EQ ! 1167: delim $$ ! 1168: .EN ! 1169: This production and action respect the left associativity of ! 1170: the minus operator, and correctly evaluate ! 1171: .CW 7-1-2 ! 1172: to 4 \(em check it by drawing a parse tree. ! 1173: .PP ! 1174: The traditional grammar generalizes to operators at $n^>=^1$ precedence levels; ! 1175: all operators at the same level have the same associativity and precedence. ! 1176: Set up a nonterminal ! 1177: .CW expr$"" sub i$ ! 1178: for precedence level $i$, with level $1$ being the lowest. ! 1179: In the traditional grammar, the nonterminals ! 1180: .CW expr , ! 1181: .CW term , ! 1182: and ! 1183: .CW factor ! 1184: correspond to ! 1185: .CW expr$"" sub 1$ , ! 1186: .CW expr$"" sub 2$ , ! 1187: and ! 1188: .CW expr$"" sub 3$ , ! 1189: respectively. ! 1190: If the operators at level $i^<^n$ are left associative, ! 1191: then the productions for ! 1192: .CW expr$"" sub i$ ! 1193: have the form ! 1194: .P{ ! 1195: expr$"" sub i$ : expr$"" sub i$ OP expr$"" sub i+1$ ; ! 1196: .P} ! 1197: Here, ! 1198: .CW OP ! 1199: represents an operator at level $i$. ! 1200: Otherwise, if the operators at level $i$ are right associative, ! 1201: then the productions have the form ! 1202: .P{ ! 1203: expr$"" sub i$ : expr$"" sub i+1$ OP expr$"" sub i$ ; ! 1204: .P} ! 1205: .PP ! 1206: At each precedence level $i^<^n$, there is an additional production of the ! 1207: form ! 1208: .P{ ! 1209: expr$"" sub i$ : expr$"" sub i+1$ ; ! 1210: .P} ! 1211: .SS "Associativity and Precedence Declarations" ! 1212: Yacc has special facilities for declaring the associativity and ! 1213: precedence of operators. ! 1214: They will be introduced by considering the ! 1215: specification in Figure _PREC_. ! 1216: .KF ! 1217: .EQ ! 1218: delim off ! 1219: .EN ! 1220: .nf ! 1221: \s5\l'\n(LLu\&\(ul'\s0 ! 1222: .fi ! 1223: .ps 9 ! 1224: .ft CB ! 1225: .PS ! 1226: [ ! 1227: define text @ [ ! 1228: B: box ht vs wid pagewid invis ! 1229: $1 ljust at B.w + 20/72,0 ! 1230: ] @ ! 1231: down ! 1232: text("%{") ! 1233: text("#def\&ine YYSTYPE double") ! 1234: text("%}") ! 1235: text("%token NUMBER") ! 1236: text("%left '+' '-'") ! 1237: text("%left '*' '/'") ! 1238: text("%right '^'") ! 1239: text("%left '~' UMINUS") ! 1240: text("%%") ! 1241: text("lines : lines expr '\en' { printf(\"%g\en\", $expr); }") ! 1242: text(" | lines '\en'") ! 1243: text(" | /* empty */") ! 1244: text(" ;") ! 1245: text("expr : expr '+' expr { $$ = $1 + $3; }") ! 1246: text(" | expr '-' expr { $$ = $1 - $3; }") ! 1247: text(" | expr '*' expr { $$ = $1 * $3; }") ! 1248: text(" | expr '/' expr { $$ = $1 / $3; }") ! 1249: text(" | '-' expr %prec UMINUS { $$ = - $expr; }") ! 1250: text(" | '~' expr { $$ = - $expr; }") ! 1251: text(" | expr '^' expr { $$ = pow($1, $3); }") ! 1252: text(" | '(' expr ')' { $$ = $expr; }") ! 1253: text(" | NUMBER") ! 1254: text(" ;") ! 1255: ] ! 1256: .PE ! 1257: .@tag FI _PREC_ ! 1258: .FI _PREC_ ! 1259: An expression evaluator based on precedence declarations for tokens. ! 1260: .EF 0 ! 1261: .nf ! 1262: \s5\l'\n(LLu\&\(ul'\s0 ! 1263: .fi ! 1264: .SP ! 1265: .EQ ! 1266: delim $$ ! 1267: .EN ! 1268: .KE ! 1269: .PP ! 1270: The tokens of the evaluator in Figure _PREC_ are ! 1271: parentheses, ! 1272: .CW NUMBER , ! 1273: and the operators ! 1274: .P{ ! 1275: \&'+' '-' '*' '/' '^' '~' UMINUS ! 1276: .P} ! 1277: (Ignore ! 1278: .CW ~ ! 1279: and ! 1280: .CW UMINUS ! 1281: for the moment.) ! 1282: .PP ! 1283: The associativity and precedence of tokens are declared on ! 1284: lines beginning with one of the keywords ! 1285: .CW %left , ! 1286: .CW %right , ! 1287: or ! 1288: .CW %nonassoc . ! 1289: All of the tokens on a line have the same associativity and ! 1290: precedence; they have lower precedence than operators on successive lines. ! 1291: These declarations will be referred to as ! 1292: .I precedence ! 1293: declarations. ! 1294: .PP ! 1295: (The keyword ! 1296: .CW %nonassoc ! 1297: is used to describe operators that must not associate with themselves; ! 1298: for example, ! 1299: .P{ ! 1300: A .LT. B .LT. C ! 1301: .P} ! 1302: is illegal in Fortran because ! 1303: .CW .LT. ! 1304: is nonassociative.) ! 1305: .PP ! 1306: The precedence declarations ! 1307: .P{ ! 1308: %left '+' '-' ! 1309: %left '*' '/' ! 1310: %right '^' ! 1311: .P} ! 1312: specify that ! 1313: .CW + ! 1314: and ! 1315: .CW - ! 1316: are left associative and have lower ! 1317: precedence than the left-associative operators ! 1318: .CW * ! 1319: and ! 1320: .CW / , ! 1321: which in turn have lower precedence than the right-associative operator ! 1322: .CW ^ . ! 1323: .PP ! 1324: The operator ! 1325: .CW ^ ! 1326: in the grammar ! 1327: represents exponentiation, as in ! 1328: .CW 2^3 , ! 1329: which evaluates to 8. ! 1330: This operator is right associative; ! 1331: thus, ! 1332: .CW 2^2^3 ! 1333: is equivalent to ! 1334: .CW 2^(2^3) . ! 1335: .PP ! 1336: The nonterminals of the grammar are ! 1337: .CW lines ! 1338: and ! 1339: .CW expr . ! 1340: The grammar expects a sequence of expressions, on separate lines. ! 1341: A typical production for ! 1342: .CW expr ! 1343: has the form ! 1344: .EQ ! 1345: delim off ! 1346: .EN ! 1347: .P{ ! 1348: expr : expr '+' expr { $$ = $1 + $3; } ! 1349: .P} ! 1350: Alternatively, we can write the action as ! 1351: .P{ ! 1352: expr : expr '+' expr { $$ = $expr#1 + $expr#2; } ! 1353: .P} ! 1354: .EQ ! 1355: delim $$ ! 1356: .EN ! 1357: .PP ! 1358: With these precedence declarations, the expression ! 1359: .P{ ! 1360: 2 ^ 2 ^ 3 * 4 - 5 * 6 - 7 * 8 ! 1361: .P} ! 1362: is evaluated as if it were parenthesized as ! 1363: .P{ ! 1364: ( (2^(2^3))*4 - 5*6 ) - 7*8 ! 1365: .P} ! 1366: .PP ! 1367: The programs section for the evaluator is in Figure _PRECB_. ! 1368: The lexical analyzer ! 1369: .CW yylex ! 1370: returns a token each time it is called. ! 1371: It skips blanks. ! 1372: If it sees a digit or a decimal point, it ! 1373: returns the token ! 1374: .CW NUMBER ! 1375: after using the ! 1376: C library function ! 1377: .CW scanf ! 1378: to read a number into the global variable ! 1379: .CW yylval ! 1380: (as mentioned in Section 1, the attribute value, if any, ! 1381: associated with a token ! 1382: must be left in ! 1383: .CW yylval ). ! 1384: Otherwise, the lexical analyzer returns a character as a token. ! 1385: .KF ! 1386: .EQ ! 1387: delim off ! 1388: .EN ! 1389: .nf ! 1390: \s5\l'\n(LLu\&\(ul'\s0 ! 1391: .fi ! 1392: .ps 9 ! 1393: .ft CB ! 1394: .PS ! 1395: [ ! 1396: define text @ [ ! 1397: B: box ht vs wid pagewid invis ! 1398: $1 ljust at B.w + 20/72,0 ! 1399: ] @ ! 1400: down ! 1401: text("%%") ! 1402: text("#include <stdio.h>") ! 1403: text("#include <ctype.h>") ! 1404: text("#include <math.h>") ! 1405: text("int yylex() {") ! 1406: text(" int c;") ! 1407: text(" while ( ( c = getchar() ) == ' ' );") ! 1408: text(" if ( (c == '.') || (isdigit(c)) ) {") ! 1409: text(" ungetc(c, stdin);") ! 1410: text(" scanf(\"%le\", &yylval);") ! 1411: text(" return NUMBER;") ! 1412: text(" }") ! 1413: text(" return c;") ! 1414: text("}") ! 1415: text("int main() { return yyparse(); }") ! 1416: text("void yyerror(s) char * s; { fprintf(stderr, \"%s\en\", s); }") ! 1417: ] ! 1418: .PE ! 1419: .@tag FI _PRECB_ ! 1420: .FI _PRECB_ ! 1421: Programs section for the evaluator in Figure _PREC_. ! 1422: .EF 0 ! 1423: .nf ! 1424: \s5\l'\n(LLu\&\(ul'\s0 ! 1425: .fi ! 1426: .SP ! 1427: .EQ ! 1428: delim $$ ! 1429: .EN ! 1430: .KE ! 1431: .PP ! 1432: The parser uses precedence declarations to decide when to apply a production. ! 1433: Suppose that the input has the form ! 1434: .P{ ! 1435: expr * expr \&\f1$...$\fP ! 1436: .P} ! 1437: and the parser has to decide whether or not to apply the ! 1438: multiplication production ! 1439: .P{ ! 1440: expr : expr '*' expr ! 1441: .P} ! 1442: If the next symbol in the input is ! 1443: .CW + , ! 1444: as in ! 1445: .P{ ! 1446: expr * expr + \&\f1$...$\fP ! 1447: .P} ! 1448: the parser applies the multiplication production because the ! 1449: token ! 1450: .CW + ! 1451: has lower precedence than ! 1452: .CW * . ! 1453: However, if the next symbol in the input is ! 1454: .CW ^ , ! 1455: the parser defers the multiplication production because ! 1456: .CW ^ ! 1457: has higher precedence than ! 1458: .CW * . ! 1459: .PP ! 1460: The treatment of the unary minus operator deserves special mention. ! 1461: The evaluator in Figure _PREC_ accepts the expression ! 1462: .CW 10^-1 ! 1463: in lieu of $10 sup -1~==~0.1$. ! 1464: In other words, ! 1465: .CW 10^-1 ! 1466: is treated like ! 1467: .CW 10^(-1) , ! 1468: with unary minus having higher precedence than ! 1469: .CW ^ . ! 1470: To help distinguish between the two uses of the minus operator, ! 1471: the evaluator recognizes ! 1472: .CW ~ ! 1473: as a synonym for unary minus. ! 1474: Unary ! 1475: .CW ~ ! 1476: has the highest precedence and binary ! 1477: .CW - ! 1478: has the lowest precedence in Figure _PREC_. ! 1479: The expression ! 1480: .CW 3-10^~1 ! 1481: is therefore equivalent to ! 1482: .CW 3-(10^(~1)) . ! 1483: .PP ! 1484: The keyword ! 1485: .CW %prec ! 1486: in the production ! 1487: .P{ ! 1488: expr : '-' expr %prec UMINUS ! 1489: .P} ! 1490: specifies that the precedence of the unary minus operator is ! 1491: taken from that of the token ! 1492: .CW UMINUS . ! 1493: Since ! 1494: .CW ~ ! 1495: has this same precedence, ! 1496: .CW 3-10^-1 ! 1497: is equivalent to ! 1498: .CW 3-(10^(-1)) . ! 1499: .PP ! 1500: The ! 1501: .CW %prec ! 1502: keyword is used to override the precedence of the tokens ! 1503: on the right side of a production. ! 1504: Without ! 1505: .CW %prec ! 1506: the parser uses the precedence of the last token on the right ! 1507: side to decide whether to apply a production. ! 1508: Thus, the ! 1509: .CW %prec ! 1510: in ! 1511: .P{ ! 1512: expr : '(' TYPENAME ')' expr %prec TYPENAME ! 1513: .P} ! 1514: is necessary for the production to take the precedence of ! 1515: token ! 1516: .CW TYPENAME ; ! 1517: otherwise the production takes its precedence from the ! 1518: closing parenthesis. ! 1519: .PP ! 1520: It is recommended that precedence declarations ! 1521: be used in a ``cookbook'' fashion, until some experience is gained. ! 1522: How Yacc uses precedence declarations is examined further in ! 1523: Section _SH4_. ! 1524: .SS "Execution Order for Actions" ! 1525: The execution order of actions is significant because actions can ! 1526: have side effects. ! 1527: One way to visualize the order is to imagine a traversal of ! 1528: a parse tree in which the children of each node ! 1529: are visited depth-first from left to right, starting at the root. ! 1530: Suppose a node has two children $c$ and $d$, with $c$ to the left of $d$. ! 1531: .I Depth-first ! 1532: implies that all the nodes in the subtree for $c$ ! 1533: are visited before any nodes are visited in the subtree for $d$. ! 1534: The tree in Figure _FI.ACTIONS_ includes actions as pseudo-symbols, ! 1535: attached by dashed lines. ! 1536: Actions are executed in the order they would be visited ! 1537: in a depth-first left-to-right traversal. ! 1538: .KF ! 1539: .EQ ! 1540: define Small % size 7 "$1" % ! 1541: .EN ! 1542: .nf ! 1543: \s5\l'\n(LLu\&\(ul'\s0 ! 1544: .fi ! 1545: .nr PS 9 ! 1546: .ps 9 ! 1547: .PS ! 1548: [ ! 1549: define NUM % { ! 1550: "$Small(NUM)$" ! 1551: "$Small($NUM)^=^$1$" at Here + 0,-vs ! 1552: } % ! 1553: ! 1554: hu = .3; vu = vs; choph = vs; chopw = .7 ! 1555: boxht = vs ! 1556: ! 1557: "$expr$" ! 1558: { ! 1559: ln(-5,-3); "$expr$" ! 1560: G1:"" ! 1561: { ln(-2,-2); NUM(2) ! 1562: G2:"" ! 1563: }{ ln( 1,-2, dashed .04); "{print $Small($NUM)$}" ! 1564: G3:"" ! 1565: } ! 1566: }{ ! 1567: ln(-1,-3); "+" ! 1568: }{ ! 1569: ln( 2,-3); "$expr$" ! 1570: { ! 1571: ln(-3,-4); "$expr$" ! 1572: { ln(-2,-2); NUM(3) ! 1573: }{ ln( 1,-2, dashed .04); "{print $Small($NUM)$}" ! 1574: } ! 1575: }{ ! 1576: ln(-.5,-4); "\(**" ! 1577: }{ ! 1578: ln( 2.5,-4); "$expr$" ! 1579: { ln(-2,-4); NUM(5) ! 1580: }{ ln( 1,-4, dashed .04); "{print $Small($NUM)$}" ! 1581: } ! 1582: }{ ! 1583: ln( 5,-4, dashed .04); "{print \(**}" ! 1584: box invis wid .6 ht vs at Here ! 1585: } ! 1586: }{ ! 1587: ln( 6,-3, dashed .04); "{print +}" ! 1588: } ! 1589: ! 1590: H1: G1 + -3*hu,0 ! 1591: H2: G2 + -5*hu,-3*vu ! 1592: H3: G2.x, H2.y ! 1593: .ps 36 ! 1594: spline -> from H1 to H2 to H3 ! 1595: .ps\n(PS ! 1596: ] ! 1597: .PE ! 1598: .@tag FI _FI.ACTIONS_ ! 1599: .FI _FI.ACTIONS_ ! 1600: Actions are executed in a depth-first left-to-right order. ! 1601: .EF 0 ! 1602: .nf ! 1603: \s5\l'\n(LLu\&\(ul'\s0 ! 1604: .fi ! 1605: .SP ! 1606: .KE ! 1607: .PP ! 1608: The parse tree in Figure _FI.ACTIONS_ ! 1609: is based on the following specification of an ! 1610: infix-to-postfix translator: ! 1611: .EQ ! 1612: delim off ! 1613: .EN ! 1614: .P{ ! 1615: %token NUM ! 1616: %left '+' ! 1617: %left '*' ! 1618: %% ! 1619: expr : expr '+' expr { printf(" +"); } ! 1620: | expr '*' expr { printf(" *"); } ! 1621: | '(' expr ')' ! 1622: | NUM { printf(" %d", $NUM); } ! 1623: ; ! 1624: .P} ! 1625: .EQ ! 1626: delim $$ ! 1627: .EN ! 1628: The translation is emitted incrementally during parsing, so ! 1629: the execution order of the print statements is critical. ! 1630: The translation of ! 1631: .CW 2+3*5 ! 1632: is ! 1633: .P{ ! 1634: 2 3 5 * + ! 1635: .P} ! 1636: .SS "Actions Embedded Within Rules" ! 1637: Yacc permits an action to be written in the middle of a production ! 1638: as well as at the end; such actions are called ! 1639: .I embedded ! 1640: actions. ! 1641: .PP ! 1642: Embedded actions are useful for keeping track of context information. ! 1643: In the EQN grammar, the context includes the current point size. ! 1644: The EQN input ! 1645: .P{ ! 1646: E sub 1 ! 1647: .P} ! 1648: is typeset as $E sub 1$. ! 1649: Note that the subscript $1$ has a smaller point size than $E$. ! 1650: Nonterminal ! 1651: .CW box ! 1652: in the following production represents an EQN construct. ! 1653: The current point size is maintained in variable ! 1654: .CW ps . ! 1655: The embedded action ! 1656: .CW ps$^$-=$^$del ! 1657: reduces the point size before the subscript box ! 1658: is processed; the other action ! 1659: .CW ps$^$+=$^$del ! 1660: restores the point size. ! 1661: Token ! 1662: .CW SUB ! 1663: represents the input characters ! 1664: .CW sub . ! 1665: .P{ ! 1666: box : box { ps -= del; } SUB box { ps += del; } ! 1667: .P} ! 1668: .PP ! 1669: Embedded actions are implemented by manufacturing a fresh ! 1670: nonterminal with one production deriving the empty string. ! 1671: Yacc actually treats this EQN example as if it had been ! 1672: written: ! 1673: .EQ ! 1674: delim off ! 1675: .EN ! 1676: .P{ ! 1677: box : box $ACT SUB box ! 1678: { ps +=del; } ! 1679: ; ! 1680: $ACT : /* empty */ ! 1681: { ps -= del; } ! 1682: .P} ! 1683: Here ! 1684: .CW $ACT ! 1685: is a fresh nonterminal. ! 1686: .PP ! 1687: Section _SH6_ considers the use of embedded actions ! 1688: to pass left-to-right context in a Yacc specification. ! 1689: .PP ! 1690: Embedded actions can have associated attribute values; ! 1691: within an embedded action, ! 1692: .CW $$ ! 1693: refers to its attribute value, not to the attribute of the ! 1694: left side of the production. ! 1695: Thus, 1 is the attribute value for the embedded action in ! 1696: .P{ ! 1697: a : b { $$ = 1; } c { x = $2; y = $c; } ! 1698: .P} ! 1699: The embedded action is at the second position in the right ! 1700: side, so its value is referred to as ! 1701: .CW $2 ! 1702: in the assignment ! 1703: .CW x=$2 . ! 1704: Note that ! 1705: .CW c ! 1706: is at position 3, so the above production can be ! 1707: rewritten using ! 1708: .CW $3 ! 1709: instead of ! 1710: .CW $c : ! 1711: .P{ ! 1712: a : b { $$ = 1; } c { x = $2; y = $3; } ! 1713: .P} ! 1714: .EQ ! 1715: delim $$ ! 1716: .EN ! 1717: .@tag SH _SH3_ ! 1718: .SH _SH3_ "How The Parser Works" ! 1719: Some familiarity with parsing is helpful ! 1720: in deciphering messages from Yacc ! 1721: about ``shift/reduce'' and ``reduce/reduce'' conflicts. ! 1722: Such messages merit investigation; they are a warning that ! 1723: the generated parser will make choices that may or may not be ! 1724: consistent with the grammar designer's intent. ! 1725: .PP ! 1726: When invoked with the ! 1727: .CW -v ! 1728: (for verbose) option, ! 1729: Yacc places a human-readable description of the generated parser ! 1730: into the file ! 1731: .CW y.output . ! 1732: This section deals with the parsing background behind ! 1733: .CW y.output ! 1734: files; parsing conflicts themselves are considered in Section _SH4_. ! 1735: .PP ! 1736: The running example in this section is the following grammar for ! 1737: real numbers: ! 1738: .P{ ! 1739: %token D P ! 1740: %% ! 1741: real : intp P frac ; ! 1742: intp : D | intp D ; ! 1743: frac : D | D frac ; ! 1744: .P} ! 1745: The abbreviated names ! 1746: .CW intp ! 1747: for integer part, ! 1748: .CW frac ! 1749: for fraction, ! 1750: and ! 1751: .CW D ! 1752: for digit, conserve space in diagrams. ! 1753: The use of token ! 1754: .CW P ! 1755: for a decimal point ! 1756: .CW '.' ! 1757: avoids confusion with other uses of dots within ! 1758: .CW y.output ! 1759: files. ! 1760: .SS "Shift-Reduce Parsing" ! 1761: A ! 1762: .I "bottom-up" ! 1763: parser works from the leaves (bottom) of a parse tree towards the ! 1764: root. ! 1765: The following sequence of tree snapshots illustrates a bottom-up ! 1766: parse of the token stream ! 1767: .CW DDPDD , ! 1768: corresponding to the real number ! 1769: .CW 21.89 . ! 1770: For the moment, the digit represented by a token ! 1771: .CW D ! 1772: appears below the token. ! 1773: The trees are ! 1774: .KS ! 1775: .ps 9 ! 1776: .ft CB ! 1777: .PS ! 1778: [ ! 1779: define D % { ! 1780: "\f2\s8D\s0\fP" ! 1781: "\s6$1\s0" at Here + 0,-.5*vs ! 1782: } % ! 1783: define Pt % { ! 1784: "\f2\s8P\s0\fP" ! 1785: "." at Here + 0,-.5*vs ! 1786: } % ! 1787: ! 1788: hu = .125; vu = 1.5*vs; choph = vs; chopw = .4 ! 1789: boxht = vs; boxwid = .8*vs; movewid = .5 ! 1790: ! 1791: S1: [ ! 1792: # "$real$" ! 1793: { ! 1794: ln(-1,-1, invis); # "$intp$" ! 1795: { ! 1796: ln(-1,-1, invis); # "$intp$" ! 1797: ln( 0,-1, invis); D(2) ! 1798: }{ ! 1799: ln( 0,-2, invis); D(1) ! 1800: } ! 1801: }{ ! 1802: ln( 0,-3, invis); Pt ! 1803: }{ ! 1804: ln( 1,-1, invis); # "$frac$" ! 1805: { ! 1806: ln( 0,-2, invis); D(8) ! 1807: }{ ! 1808: ln( 1,-1, invis); # "$frac$" ! 1809: ln( 0,-1, invis); D(9) ! 1810: } ! 1811: } ! 1812: ] ! 1813: move ! 1814: S2: [ ! 1815: # "$real$" ! 1816: { ! 1817: ln(-1,-1, invis); # "$intp$" ! 1818: { ! 1819: ln(-1,-1, invis); "$intp$" ! 1820: ln( 0,-1); D(2) ! 1821: }{ ! 1822: ln( 0,-2, invis); D(1) ! 1823: } ! 1824: }{ ! 1825: ln( 0,-3, invis); Pt ! 1826: }{ ! 1827: ln( 1,-1, invis); # "$~~frac$" ! 1828: { ! 1829: ln( 0,-2, invis); D(8) ! 1830: }{ ! 1831: ln( 1,-1, invis); # "$frac$" ! 1832: ln( 0,-1, invis); D(9) ! 1833: } ! 1834: } ! 1835: ] ! 1836: move ! 1837: S3: [ ! 1838: # "$real$" ! 1839: { ! 1840: ln(-1,-1, invis); "$intp~$" ! 1841: { ! 1842: ln(-1,-1); "$intp$" ! 1843: ln( 0,-1); D(2) ! 1844: }{ ! 1845: ln( 0,-2); D(1) ! 1846: } ! 1847: }{ ! 1848: ln( 0,-3, invis); Pt ! 1849: }{ ! 1850: ln( 1,-1, invis); # "$~~frac$" ! 1851: { ! 1852: ln( 0,-2, invis); D(8) ! 1853: }{ ! 1854: ln( 1,-1, invis); # "$frac$" ! 1855: ln( 0,-1, invis); D(9) ! 1856: } ! 1857: } ! 1858: ] ! 1859: move ! 1860: S4: [ ! 1861: # "$real$" ! 1862: { ! 1863: ln(-1,-1, invis); "$intp~$" ! 1864: { ! 1865: ln(-1,-1); "$intp$" ! 1866: ln( 0,-1); D(2) ! 1867: }{ ! 1868: ln( 0,-2); D(1) ! 1869: } ! 1870: }{ ! 1871: ln( 0,-3, invis); Pt ! 1872: }{ ! 1873: ln( 1,-1, invis); # "$frac$" ! 1874: { ! 1875: ln( 0,-2, invis); D(8) ! 1876: }{ ! 1877: ln( 1,-1, invis); "$frac$" ! 1878: ln( 0,-1); D(9) ! 1879: } ! 1880: } ! 1881: ] ! 1882: move ! 1883: S5: [ ! 1884: # "$real$" ! 1885: { ! 1886: ln(-1,-1, invis); "$intp~~$" ! 1887: { ! 1888: ln(-1,-1); "$intp$" ! 1889: ln( 0,-1); D(2) ! 1890: }{ ! 1891: ln( 0,-2); D(1) ! 1892: } ! 1893: }{ ! 1894: ln( 0,-3, invis); Pt ! 1895: }{ ! 1896: ln( 1,-1, invis); "$~~frac$" ! 1897: { ! 1898: ln( 0,-2); D(8) ! 1899: }{ ! 1900: ln( 1,-1); "$frac$" ! 1901: ln( 0,-1); D(9) ! 1902: } ! 1903: } ! 1904: ] ! 1905: move ! 1906: S6: [ ! 1907: "$real$" ! 1908: { ! 1909: ln(-1,-1); "$intp~~$" ! 1910: { ! 1911: ln(-1,-1); "$intp$" ! 1912: ln( 0,-1); D(2) ! 1913: }{ ! 1914: ln( 0,-2); D(1) ! 1915: } ! 1916: }{ ! 1917: ln( 0,-3); Pt ! 1918: }{ ! 1919: ln( 1,-1); "$~~frac$" ! 1920: { ! 1921: ln( 0,-2); D(8) ! 1922: }{ ! 1923: ln( 1,-1); "$frac$" ! 1924: ln( 0,-1); D(9) ! 1925: } ! 1926: } ! 1927: ] ! 1928: ! 1929: "$=>$" at .5<S1.e, S2.w> ! 1930: "$=>$" at .5<S2.e, S3.w> ! 1931: "$=>$" at .5<S3.e, S4.w> ! 1932: "$=>$" at .5<S4.e, S5.w> ! 1933: "$=>$" at .5<S5.e, S6.w> ! 1934: ] ! 1935: .PE ! 1936: .KE ! 1937: .LP ! 1938: Let us redraw these trees to line up their uncovered portions; ! 1939: that is, the roots of the completed subtrees. ! 1940: The redrawn trees are ! 1941: .KS ! 1942: .ps 9 ! 1943: .PS ! 1944: [ ! 1945: define D % { ! 1946: "\f2\s8D\s0\fP" ! 1947: } % ! 1948: define Pt % { ! 1949: "\f2\s8P\s0\fP" ! 1950: # "." at Here + 0,-.5*vs ! 1951: } % ! 1952: ! 1953: hu = .125; vu = 1.5*vs; choph = vs; chopw = .4 ! 1954: boxht = vs; boxwid = .8*vs; movewid = hu; sep = .5 ! 1955: ! 1956: ! 1957: S1: [ ! 1958: D(1); move; D(2); move; Pt; move; D(8); move; D(9) ! 1959: ] ! 1960: ! 1961: S2: [ ! 1962: { ! 1963: "$intp~~$"; ln( 0,-1); D(1) ! 1964: } ! 1965: move ! 1966: D(2); move; Pt; move; D(8); move; D(9) ! 1967: ] with .nw at S1.ne + sep,0 ! 1968: ! 1969: S3: [ ! 1970: { ! 1971: "$intp~~$" ! 1972: { ! 1973: ln(-1,-1); "$intp$" ! 1974: ln( 0,-1); D(1) ! 1975: }{ ! 1976: ln( 0,-2); D(2) ! 1977: } ! 1978: } ! 1979: move ! 1980: Pt; move; D(8); move; D(9) ! 1981: ] with .nw at S2.ne + sep,0 ! 1982: ! 1983: S4: [ ! 1984: { ! 1985: "$intp~~$" ! 1986: { ! 1987: ln(-1,-1); "$intp$" ! 1988: ln( 0,-1); D(1) ! 1989: }{ ! 1990: ln( 0,-2); D(2) ! 1991: } ! 1992: } ! 1993: move ! 1994: Pt; move; D(8) ! 1995: move ! 1996: { ! 1997: "$~~frac$"; ln( 0,-1); D(9) ! 1998: } ! 1999: ] with .nw at S3.ne + sep,0 ! 2000: ! 2001: S5: [ ! 2002: { ! 2003: "$intp~~$" ! 2004: { ! 2005: ln(-1,-1); "$intp$" ! 2006: ln( 0,-1); D(1) ! 2007: }{ ! 2008: ln( 0,-2); D(2) ! 2009: } ! 2010: } ! 2011: move ! 2012: Pt ! 2013: move ! 2014: { ! 2015: "$~~frac$" ! 2016: { ! 2017: ln( 0,-2); D(8) ! 2018: }{ ! 2019: ln( 1,-1); "$frac$" ! 2020: ln( 0,-1); D(9) ! 2021: } ! 2022: } ! 2023: ] with .nw at S4.ne + sep,0 ! 2024: ! 2025: S6: [ ! 2026: "$real$" ! 2027: { ! 2028: ln(-1,-1); "$intp~~$" ! 2029: { ! 2030: ln(-1,-1); "$intp$" ! 2031: ln( 0,-1); D(1) ! 2032: }{ ! 2033: ln( 0,-2); D(2) ! 2034: } ! 2035: }{ ! 2036: ln( 0,-3); Pt ! 2037: }{ ! 2038: ln( 1,-1); "$~~frac$" ! 2039: { ! 2040: ln( 0,-2); D(8) ! 2041: }{ ! 2042: ln( 1,-1); "$frac$" ! 2043: ln( 0,-1); D(9) ! 2044: } ! 2045: } ! 2046: ] with .nw at S5.ne + sep,0 ! 2047: ! 2048: "$=>~$" at .5<S1.ne, S2.nw> ! 2049: "$=>$" at .5<S2.ne, S3.nw> ! 2050: "$=>$" at .5<S3.ne, S4.nw> ! 2051: "$~~=>$" at .5<S4.ne, S5.nw> ! 2052: "$=>$" at .5<S5.ne, S6.nw> ! 2053: ] ! 2054: .PE ! 2055: .KE ! 2056: .PP ! 2057: Shift-reduce parsers store only the uncovered portions of a ! 2058: parse tree, as in ! 2059: the following ! 2060: snapshots, obtained from the ! 2061: preceding sequence of trees: ! 2062: .KS ! 2063: .ps 9 ! 2064: .PS ! 2065: [ ! 2066: define N % box invis $1 wid .25 % ! 2067: define D % box invis "\f2\s8D\s0\fP" wid .125 % ! 2068: define P % box invis "\f2\s8P\s0\fP" wid .125 % ! 2069: define derives % box invis wid .4 "$=>$" % ! 2070: ! 2071: boxht = vs; boxwid = .8*vs ! 2072: ! 2073: ! 2074: [ D; D; P; D; D ] ! 2075: derives ! 2076: [ N("$intp$"); D; P; D; D ] ! 2077: derives ! 2078: [ N("$intp$"); P; D; D ] ! 2079: derives ! 2080: [ N("$intp$"); P; D; N("$frac$") ] ! 2081: derives ! 2082: [ N("$intp$"); P; N("$frac$") ] ! 2083: derives ! 2084: [ N("$real$") ] ! 2085: ] ! 2086: .PE ! 2087: .KE ! 2088: .PP ! 2089: Such derivations can be broken down ! 2090: into sequences of shift and ! 2091: reduce actions. ! 2092: A ! 2093: .I shift ! 2094: action advances the parser to the next unexamined input token; ! 2095: such tokens are called ! 2096: .I lookahead ! 2097: symbols. ! 2098: A ! 2099: .I reduce ! 2100: action replaces the right side of a production by its left side. ! 2101: The key problem of shift-reduce parsing is that of deciding ! 2102: when to shift and when to reduce; Yacc generates tables for ! 2103: this purpose that are explained later in this section. ! 2104: .EQ ! 2105: delim off ! 2106: .EN ! 2107: .PP ! 2108: A shift-reduce parse of the input token stream ! 2109: .CW DDPDD ! 2110: appears in Figure _FI.SHIFTREDUCE_. ! 2111: A special token ! 2112: .CW $end ! 2113: marks the end of the input. ! 2114: Within each snapshot, a pointer appears before the ! 2115: current lookahead symbol. ! 2116: The first action, a shift, advances the pointer past the ! 2117: leftmost ! 2118: .CW D : ! 2119: .EQ ! 2120: delim $$ ! 2121: .EN ! 2122: .KF ! 2123: .nf ! 2124: \s5\l'\n(LLu\&\(ul'\s0 ! 2125: .fi ! 2126: .ps 9 ! 2127: .PS ! 2128: [ ! 2129: define N % box invis $1 wid .25 % ! 2130: define D % box invis "\f2\s8D\s0\fP" wid .125 % ! 2131: define P % box invis "\f2\s8P\s0\fP" wid .125 % ! 2132: define E % box invis "$f2($end)$" wid .3 % ! 2133: define action % Act: [ ! 2134: right ! 2135: B: box invis wid actionwid ! 2136: PTR: box invis wid .1 ! 2137: $1 ljust at B.w ! 2138: ] with .PTR.n at S.PTR.s % ! 2139: define shift % action("shift") % ! 2140: define reduce % action("reduce") % ! 2141: define ptr % ! 2142: PTR: box invis wid .1; { move left .025; up; line <- } ! 2143: % ! 2144: define handle % { line from last box.sw to last box.se } % ! 2145: ! 2146: boxht = vs ! 2147: arrowht = .05; arrowwid = .025; lineht = .75*vs; dy = vs ! 2148: ! 2149: down ! 2150: ! 2151: actionwid = .9 ! 2152: T1: S:[ right ! 2153: ptr; D; D; P; D; D; E ! 2154: ] ! 2155: shift ! 2156: S:[ right ! 2157: D; handle; ptr; D; P; D; D; E ! 2158: ] with .PTR.n at Act.PTR.s ! 2159: reduce ! 2160: S:[ right ! 2161: N("$intp$"); ptr; D; P; D; D; E ! 2162: ] with .PTR.n at Act.PTR.s ! 2163: shift ! 2164: S:[ right ! 2165: N("$intp$"); handle; D; handle; ptr; P; D; D; E ! 2166: ] with .PTR.n at Act.PTR.s ! 2167: reduce ! 2168: S:[ right ! 2169: N("$intp$"); ptr; P; D; D; E ! 2170: ] with .PTR.n at Act.PTR.s ! 2171: shift ! 2172: B1: S:[ right ! 2173: N("$intp$"); P; ptr; D; D; E ! 2174: ] with .PTR.n at Act.PTR.s ! 2175: ! 2176: ! 2177: ! 2178: actionwid = 1.2 ! 2179: T2: S:[ right ! 2180: box invis wid actionwid ! 2181: PTR: box invis wid .05 ! 2182: ] with .sw at T1.se + 1.2,0 ! 2183: shift ! 2184: S:[ right ! 2185: N("$intp$"); P; D; ptr; D; E ! 2186: ] with .PTR.n at Act.PTR.s ! 2187: shift ! 2188: S:[ right ! 2189: N("$intp$"); P; D; D; handle; ptr; E ! 2190: ] with .PTR.n at Act.PTR.s ! 2191: reduce ! 2192: S:[ right ! 2193: N("$intp$"); P; D; handle; N("$frac$"); handle; ptr; E ! 2194: ] with .PTR.n at Act.PTR.s ! 2195: reduce ! 2196: S:[ right ! 2197: N("$intp$"); handle; P; handle; N("$frac$"); handle; ptr; E ! 2198: ] with .PTR.n at Act.PTR.s ! 2199: reduce ! 2200: B2: S:[ right ! 2201: N("$real$"); ptr; E ! 2202: ] with .PTR.n at Act.PTR.s ! 2203: ! 2204: G: .5<T1.se, T2.sw> + 0,vs ! 2205: line from G to G.x, B2.s.y ! 2206: ] ! 2207: .PE ! 2208: .@tag FI _FI.SHIFTREDUCE_ ! 2209: .FI _FI.SHIFTREDUCE_ ! 2210: Shift-reduce parsing of ! 2211: .CB DDPDD . ! 2212: .EF ! 2213: .nf ! 2214: \s5\l'\n(LLu\&\(ul'\s0 ! 2215: .EF 0 ! 2216: .fi ! 2217: .SP ! 2218: .ps 9 ! 2219: .PS ! 2220: ! 2221: define N % box invis $1 wid .25 % ! 2222: define D % box invis "\f2\s8D\s0\fP" wid .125 % ! 2223: define P % box invis "\f2\s8P\s0\fP" wid .125 % ! 2224: define E % box invis wid .05; box invis "$f2($end)$" wid .25 % ! 2225: define shift % box invis wid .8 "shift" % ! 2226: define reduce % box invis wid .8 "reduce" % ! 2227: define lookahead % box invis wid .1; { move left .05; up; line <- } % ! 2228: define handle % { line from last box.sw to last box.se } % ! 2229: ! 2230: [ ! 2231: boxht = vs ! 2232: arrowht = .05; arrowwid = .025; lineht = .75*vs ! 2233: ! 2234: lookahead; D; D; P; D; D; E ! 2235: shift ! 2236: D; lookahead; D; P; D; D; E ! 2237: ] ! 2238: .PE ! 2239: .LP ! 2240: The second action reduces the token ! 2241: .CW D ! 2242: immediately to the left of the pointer ! 2243: (right sides to be reduced are underlined for clarity). ! 2244: The reduction replaces the right side ! 2245: .CW D ! 2246: by the left side ! 2247: .CW intp : ! 2248: .ps 9 ! 2249: .PS ! 2250: [ ! 2251: boxht = vs ! 2252: arrowht = .05; arrowwid = .025; lineht = .75*vs ! 2253: ! 2254: D; handle; lookahead; D; P; D; D; E ! 2255: reduce ! 2256: N("$intp$"); lookahead; D; P; D; D; E ! 2257: ] ! 2258: .PE ! 2259: .LP ! 2260: After the next ! 2261: .CW D ! 2262: is shifted, the right side ! 2263: .CW intp$~$D ! 2264: is reduced to the left side ! 2265: .CW intp : ! 2266: .ps 9 ! 2267: .PS ! 2268: [ ! 2269: boxht = vs ! 2270: arrowht = .05; arrowwid = .025; lineht = .75*vs ! 2271: ! 2272: N("$intp$"); handle; D; handle; lookahead; P; D; D; E ! 2273: reduce ! 2274: N("$intp$"); lookahead; P; D; D; E ! 2275: ] ! 2276: .PE ! 2277: .LP ! 2278: Successive shift actions now advance the lookahead pointer all the way ! 2279: to the endmarker. ! 2280: Finally, a sequence of reduce actions completes the parse. ! 2281: .PP ! 2282: It is no accident that a right side to be reduced always appears ! 2283: immediately to the left of the pointer in Figure _FI.SHIFTREDUCE_. ! 2284: This observation is the basis for a stack-implementation of shift-reduce ! 2285: parsing. ! 2286: Informally, the symbols to the left of the pointer ! 2287: are held on a stack, so a right side to ! 2288: be reduced appears at the top of the stack. ! 2289: .PP ! 2290: Parsers generated by Yacc use a stack; however, instead of symbols ! 2291: the stack holds states. ! 2292: It is these states that are displayed in a ! 2293: .CW y.output ! 2294: file. ! 2295: .SS "Parser States" ! 2296: How does a parser know that a digit to the left of a decimal point ! 2297: reduces to ! 2298: .CW intp , ! 2299: but that a digit to the right reduces to ! 2300: .CW frac ? ! 2301: The parser uses states to summarize prior parsing actions. ! 2302: Some of ! 2303: the states of the real-number parser are (informally) ! 2304: .SP .5 ! 2305: .IP 0. 4 ! 2306: .I "The starting state" . ! 2307: The very first token must be a ! 2308: .CW D ; ! 2309: it reduces to ! 2310: .CW intp . ! 2311: .SP .5 ! 2312: .IP 2. ! 2313: .I "Within the integer part" . ! 2314: An ! 2315: .CW intp ! 2316: has been seen. ! 2317: The lookahead token must either be a ! 2318: .CW D ! 2319: (another digit in the integer part) ! 2320: or a ! 2321: .CW P ! 2322: (the decimal point). ! 2323: .SP .5 ! 2324: .IP 7. ! 2325: .I "Within the fraction part" . ! 2326: Shift as long as the lookahead token is a ! 2327: .CW D . ! 2328: Otherwise, reduce the last ! 2329: .CW D ! 2330: to ! 2331: .CW frac . ! 2332: .SP .5 ! 2333: .PP ! 2334: State 2 is displayed as follows in the ! 2335: .CW y.output ! 2336: file for the real-number grammar: ! 2337: .P{ ! 2338: state 2 ! 2339: real : intp.P frac ! 2340: intp : intp.D ! 2341: .sp .5 ! 2342: .ft CW ! 2343: D shift 5 ! 2344: P shift 4 ! 2345: . error ! 2346: .P} ! 2347: .LP ! 2348: A ! 2349: .I state ! 2350: consists of a collection of items, where an ! 2351: .I item ! 2352: is a production with a dot inserted in the right side\(emsome ! 2353: versions of Yacc use an underscore to mark the position of the dot. ! 2354: The items of state 2 are ! 2355: .P{ ! 2356: real : intp.P frac ! 2357: intp : intp.D ! 2358: .P} ! 2359: In this state, the parser shifts on lookahead ! 2360: .CW P . ! 2361: The shift is recorded by (conceptually) moving the dot past ! 2362: .CW P ! 2363: to obtain the item ! 2364: .P{ ! 2365: real : intp P.frac ! 2366: .P} ! 2367: This item is the sole item in state 4. ! 2368: In words, state 4 records that a ! 2369: .CW P ! 2370: has been seen and that the incoming tokens are now ! 2371: expected to match ! 2372: .CW frac . ! 2373: .PP ! 2374: The states and their transitions constitute an automaton. ! 2375: The automaton for the real-number grammar appears in ! 2376: Figure _FI.GOTO_. ! 2377: The solid arrows are for shift transitions, due to tokens. ! 2378: The dashed arrows, for transitions due to nonterminals, are used ! 2379: during reductions. ! 2380: .KF ! 2381: .nf ! 2382: \s5\l'\n(LLu\&\(ul'\s0 ! 2383: .fi ! 2384: .nr PS 9 ! 2385: .ps 9 ! 2386: .PS ! 2387: [ ! 2388: define state % ! 2389: if "$4"!="" then 'nitems=$4' else 'nitems=1' ! 2390: S$1: box fill at O + $2*hu, $3*vu ht nitems*vs ! 2391: "$1" at S$1.n + 0,vs/2 ! 2392: % ! 2393: ! 2394: arcrad = vs/3; boxht = vs; boxwid = 1.2; fillval = 1 ! 2395: dashwid = .03 ! 2396: hu = .7; vu = 4*vs ! 2397: ! 2398: O: "" ! 2399: state(0, 0, 0) ! 2400: box invis "$f2($accept)^:~cdot~real~f2($end)$" at S0 ! 2401: ! 2402: state(1, 3, 0) ! 2403: box invis "$f2($accept)^:~real~cdot~f2($end)$" at S1 ! 2404: ! 2405: state(2, 1,-1, 2) ! 2406: [ down ! 2407: B1: box invis ! 2408: B2: box invis ! 2409: "$real^:~intp~cdot~P~frac$" ljust at B1.w + .075,0 ! 2410: "$intp^:~intp~cdot~D$" ljust at B2.w + .075,0 ! 2411: ] at S2 ! 2412: ! 2413: state(5, 4,-1) ! 2414: box invis "$intp^:~intp~D~cdot$" at S5 ! 2415: ! 2416: state(4, 2,-2) ! 2417: box invis "$real^:~intp~P~cdot~frac$" at S4 ! 2418: ! 2419: state(6, 5,-2) ! 2420: box invis "$real^:~intp~P~frac~cdot$" at S6 ! 2421: ! 2422: state(7, 3,-3, 2) ! 2423: [ down ! 2424: B1: box invis ! 2425: B2: box invis ! 2426: box invis "$frac^:~D~cdot$" ljust at B1.w + .1,0 ! 2427: box invis "$frac^:~D~cdot~frac$" ljust at B2.w + .1,0 ! 2428: ] at S7 ! 2429: ! 2430: state(8, 6,-3) ! 2431: box invis "$frac^:~D~frac~cdot$" at S8 ! 2432: ! 2433: state(3, 0,-3) ! 2434: box invis "$intp^:~D~cdot$" at S3 ! 2435: ! 2436: S9: box invis at O + 6*hu, 0 ! 2437: "\0\0\f3accept\fP" ljust at S9.w ! 2438: ! 2439: G02: .66<S0.sw,S0.s> ! 2440: G03: .33<S0.sw,S0.s> ! 2441: G2: .5<S2.sw,S2.s> ! 2442: G4: .5<S4.sw,S4.s> ! 2443: G7a: .5<S7.sw,S7.s> ! 2444: G7b: .5<S7.s,S7.se> ! 2445: G7c: S7.s + 0,-1.5*vs ! 2446: ! 2447: line -> from S0.e to S1.w dashed ! 2448: line -> from S2.e to S5.w ! 2449: line -> from S4.e to S6.w dashed ! 2450: line -> from S7.e to S8.w dashed ! 2451: line -> from S1.e to S9.w ! 2452: line -> from G03.s to G03.x, S3.n.y ! 2453: ! 2454: adown(G02); anell(S2.w, -> dashed, dashed) ! 2455: adown(G2); anell(S4.w, ->) ! 2456: adown(G4); anell(S7.w, ->) ! 2457: adown(G7a); anell(G7c); anell(G7b, ->) ! 2458: ! 2459: "$real$" at .5<S0.e, S1.w> + 0, vs/2 ! 2460: "$intp$" at (G02.x+S2.w.x)/2, S2.y + vs/2 ! 2461: "$~D$" ljust at G03.x,S4.y ! 2462: "$f2($end)$" at .5<S1.e, S9.w> + 0, vs/2 ! 2463: "$D$" at .5<S2.e, S5.w> + 0, vs/2 ! 2464: "$P$" at (G2.x+S4.w.x)/2, S4.y + vs/2 ! 2465: "$frac$" at .5<S4.e, S6.w> + 0, vs/2 ! 2466: "$D$" at (G4.x+S7.w.x)/2, S7.y + vs/2 ! 2467: "$frac$" at .5<S7.e, S8.w> + 0, vs/2 ! 2468: "$D$" at G7c + 0, vs/2 ! 2469: ] ! 2470: .PE ! 2471: .@tag FI _FI.GOTO_ ! 2472: .FI _FI.GOTO_ ! 2473: States and transitions for the real-number grammar. ! 2474: .EF 0 ! 2475: .nf ! 2476: \s5\l'\n(LLu\&\(ul'\s0 ! 2477: .fi ! 2478: .SP ! 2479: .KE ! 2480: .PP ! 2481: The parser holds states on a stack, with the current state on ! 2482: top. ! 2483: The starting state of the automaton in Figure _FI.GOTO_ is state 0. ! 2484: With lookahead ! 2485: .CW D , ! 2486: the automaton shifts to state 3 (in the bottom-left corner of ! 2487: the figure) ! 2488: by pushing 3 onto the stack and removing the lookahead ! 2489: .CW D ! 2490: from the input. ! 2491: For ease of comparison with Figure _FI.SHIFTREDUCE_, the symbol ! 2492: .CW D ! 2493: appears below the state in the following diagram: ! 2494: .KS ! 2495: .ps 9 ! 2496: .PS ! 2497: [ ! 2498: define Disp % ! 2499: box invis $2 ! 2500: { move to last box + 0,-del; $1 } ! 2501: % ! 2502: define N % Disp($1, wid .25) % ! 2503: define D % Disp("\f2\s8D\s0\fP", wid .1) % ! 2504: define P % Disp("\f2\s8P\s0\fP", wid .1) % ! 2505: define E % Disp("$f2($end)$", wid .3) % ! 2506: define action % Act: [ ! 2507: right ! 2508: B: box invis wid 1 ! 2509: PTR: box invis wid .1 ! 2510: $1 ljust at B.w ! 2511: ] with .PTR.n at S.PTR.s % ! 2512: define shift % action("shift") % ! 2513: define reduce % action("$1") % ! 2514: define ptr % ! 2515: PTR: box invis wid .05 ! 2516: { move left .025; move up boxht/2; line <- } ! 2517: box invis wid .3 ! 2518: { move left .15; $1 } ! 2519: box invis wid .05 ! 2520: { move left .025; move up boxht/2; line <- } ! 2521: % ! 2522: define handle % { line from last box.sw to last box.se } % ! 2523: define state % [ ! 2524: down ! 2525: ELEM: box "$1" ! 2526: $2 ! 2527: $3 ! 2528: ] with .ELEM.w at Here; move to last [].ELEM.e; right % ! 2529: ! 2530: boxht = vs; boxwid = .2 ! 2531: arrowht = .05; arrowwid = .025; lineht = .5*vs; dy = vs ! 2532: movewid = .1; del = .015 ! 2533: ! 2534: L1: S:[ right ! 2535: state(0) ! 2536: ptr() ! 2537: D; D; P; D; D; E ! 2538: ] ! 2539: shift ! 2540: L2: S:[ right ! 2541: state(0); state(3, D) ! 2542: ptr() ! 2543: D; P; D; D; E ! 2544: ] with .PTR.n at Act.PTR.s + 0,-boxht/2 ! 2545: ! 2546: ] ! 2547: .PE ! 2548: .KE ! 2549: .LP ! 2550: The top of the state stack has its own pointer, separate from the ! 2551: lookahead pointer to the next input symbol. ! 2552: .PP ! 2553: The only item in state 3 is ! 2554: .P{ ! 2555: intp : D. ! 2556: .P} ! 2557: Whenever the dot in an item is at the end of the production, one of the ! 2558: possible actions is a reduction by that production. ! 2559: Since the state has no other actions, the parser chooses to reduce. ! 2560: .PP ! 2561: A reduce action has two phases: ! 2562: (a) pop the states corresponding to the right side, ! 2563: and (b) push a state corresponding to the left side. ! 2564: The following diagram illustrates the reduction of the ! 2565: leading ! 2566: .CW D ! 2567: in ! 2568: .CW DDPDD ! 2569: to ! 2570: .CW intp : ! 2571: .KS ! 2572: .ps 9 ! 2573: .PS ! 2574: [ ! 2575: define Disp % ! 2576: box invis $2 ! 2577: { move to last box + 0,-del; $1 } ! 2578: % ! 2579: define N % Disp($1, wid .25) % ! 2580: define D % Disp("\f2\s8D\s0\fP", wid .1) % ! 2581: define P % Disp("\f2\s8P\s0\fP", wid .1) % ! 2582: define E % Disp("$f2($end)$", wid .3) % ! 2583: define action % Act: [ ! 2584: right ! 2585: B: box invis wid 1 ! 2586: PTR: box invis wid .1 ! 2587: $1 ljust at B.w ! 2588: ] with .PTR.n at S.PTR.s + 0,-boxht % ! 2589: define shift % action("shift") % ! 2590: define reduce % action("$1") % ! 2591: define ptr % ! 2592: PTR: box invis wid .05 ! 2593: { move left .025; move up boxht/2; line <- } ! 2594: box invis wid .3 ! 2595: { move left .15; $1 } ! 2596: box invis wid .05 ! 2597: { move left .025; move up boxht/2; line <- } ! 2598: % ! 2599: define handle % { line from last box.sw to last box.se } % ! 2600: define state % [ ! 2601: down ! 2602: ELEM: box "$1" ! 2603: $2 ! 2604: $3 ! 2605: ] with .ELEM.w at Here; move to last [].ELEM.e; right % ! 2606: ! 2607: boxht = vs; boxwid = .2 ! 2608: arrowht = .05; arrowwid = .025; lineht = .5*vs; dy = vs ! 2609: movewid = .1; del = .015 ! 2610: ! 2611: L1: S:[ right ! 2612: state(0); state(3, D, handle) ! 2613: ptr() ! 2614: D; P; D; D; E ! 2615: ] ! 2616: reduce(pop) ! 2617: L2: S:[ right ! 2618: state(0) ! 2619: ptr("$intp$") ! 2620: D; P; D; D; E ! 2621: ] with .PTR.n at Act.PTR.s + 0,-boxht ! 2622: reduce(goto) ! 2623: L3: S:[ right ! 2624: state(0); state(2, N("$intp$")) ! 2625: ptr() ! 2626: D; P; D; D; E ! 2627: ] with .PTR.n at Act.PTR.s + 0,-boxht ! 2628: ! 2629: dx = .75; dy = -lineht-vs/2-del ! 2630: "Pop the states corresponding to the right side \f2\s8D\s0\fP."\ ! 2631: ljust at L1.ne + dx,dy ! 2632: "Prepare to push a state for the left side $intp$."\ ! 2633: ljust at L2.ne + dx,dy ! 2634: "State 0 goes to 2 under $intp$."\ ! 2635: ljust at L3.ne + dx,dy ! 2636: ! 2637: box invis wid 2.75 with .nw at L1.ne + dx,dy ! 2638: ] ! 2639: .PE ! 2640: .KE ! 2641: .SS "Parsing Actions" ! 2642: The parser has only four actions available to it, called ! 2643: shift, reduce, accept, and error. ! 2644: A move of the parser is as follows: ! 2645: .SP .5 ! 2646: .IP 1. 4 ! 2647: Based on its current state, the parser decides whether it needs a lookahead ! 2648: token to choose the next action. ! 2649: If it needs one, and does not already have one, it calls ! 2650: .CW yylex ! 2651: to obtain the next token. ! 2652: .SP .5 ! 2653: .IP 2. ! 2654: Using the current state $p$, and the lookahead token $t$ ! 2655: if needed, the parser chooses an action. ! 2656: .RS ! 2657: .SP .25 ! 2658: .IP a) 4 ! 2659: A ! 2660: .I shift ! 2661: action to state $q$ is done by pushing state $q$ onto the ! 2662: state stack and clearing the lookahead token. ! 2663: .SP .25 ! 2664: .IP b) ! 2665: A ! 2666: .I reduce ! 2667: action by a production is done in two phases. ! 2668: In the first phase, the parser pops from the stack a number of states ! 2669: equal to the number of symbols on the right side. ! 2670: Let $q$ be the ! 2671: state uncovered after the states are popped, ! 2672: and let the nonterminal on the left side of the production take $q$ to $r$. ! 2673: In the second phase, the parser pushes state $r$ ! 2674: onto the stack. ! 2675: .SP .25 ! 2676: .EQ ! 2677: delim off ! 2678: .EN ! 2679: .IP c) ! 2680: The ! 2681: .I accept ! 2682: action occurs after the entire input has been seen and matched. ! 2683: This action occurs only when the lookahead token is the endmarker ! 2684: .CW $end . ! 2685: .EQ ! 2686: delim $$ ! 2687: .EN ! 2688: .SP .25 ! 2689: .IP d) ! 2690: An ! 2691: .I error ! 2692: action occurs when the parser can no longer continue parsing ! 2693: according to the productions. ! 2694: That is, the input tokens seen so far and the current lookahead ! 2695: cannot possibly be followed by anything that would result ! 2696: in a legal input. ! 2697: Error recovery is covered in Section _SH5_. ! 2698: .RE ! 2699: .@tag SH _SH4_ ! 2700: .SH _SH4_ "Ambiguity and Conflicts" ! 2701: A ! 2702: .I "shift/reduce conflict" ! 2703: occurs if the parser cannot decide between ! 2704: a shift action and a reduce action. ! 2705: Similarly, a ! 2706: .I "reduce/reduce conflict" ! 2707: occurs if the parser cannot decide between ! 2708: two legal reductions. ! 2709: .PP ! 2710: Conflicts definitely occur when a grammar is ! 2711: .I ambiguous ; ! 2712: that is, if some input string has more than one parse tree. ! 2713: Conflicts can also occur when a grammar, although consistent, ! 2714: requires a more complex parser than Yacc is capable of ! 2715: constructing. ! 2716: Finally, conflicts are sometimes introduced when an action is embedded ! 2717: into the middle of a production. ! 2718: .PP ! 2719: Yacc produces a parser even when conflicts occur. ! 2720: Rules used to choose between two competing actions is ! 2721: called ! 2722: .I "disambiguating rules" . ! 2723: The default disambiguating rules are: ! 2724: .SP .5 ! 2725: .IP 1. 4 ! 2726: In a shift/reduce conflict, the default is to shift. ! 2727: .SP .25 ! 2728: .IP 2. ! 2729: In a reduce/reduce conflict, the default is to reduce by ! 2730: the earlier production in the specification. ! 2731: .SP .5 ! 2732: .PP ! 2733: Although the effect of disambiguating rules can often be achieved ! 2734: by rewriting the grammar to avoid conflicts, ! 2735: experience suggests that this rewriting is somewhat unnatural ! 2736: and produces slower parsers. ! 2737: .PP ! 2738: The rest of this section considers two situations; ! 2739: one in which the default disambiguating rules do not ! 2740: have the intended effect, and one in which they do. ! 2741: It is recommended that shift/reduce conflicts be ! 2742: investigated using the ! 2743: .CW y.output ! 2744: file created by running Yacc with the ! 2745: .CW -v ! 2746: option. ! 2747: .SS "To Shift or To Reduce" ! 2748: Yacc reports 2 shift/reduce conflicts when it is applied to ! 2749: .EQ ! 2750: delim off ! 2751: .EN ! 2752: .P{ ! 2753: %token NUM ! 2754: %% ! 2755: expr : expr '\en' { printf("\en"); return(0); } ! 2756: | expr '-' expr { printf(" -"); } ! 2757: | NUM { printf(" %g", $NUM); } ! 2758: ; ! 2759: .P} ! 2760: .EQ ! 2761: delim $$ ! 2762: .EN ! 2763: This specification marks the end of an expression ! 2764: by a newline character; ! 2765: the ! 2766: .CW return ! 2767: in the associated action terminates parsing immediately after ! 2768: echoing the newline. ! 2769: .PP ! 2770: The hope here is to translate an infix expression into postfix ! 2771: notation. ! 2772: Thus we want ! 2773: .P{ ! 2774: 2 - 1 - 1 ! 2775: .P} ! 2776: to be translated into ! 2777: .P{ ! 2778: 2 1 - 1 - ! 2779: .P} ! 2780: The answer would be 0 if the expression were evaluated by ! 2781: subtracting 1 from 2, and then subtracting 1 from the result. ! 2782: Unfortunately, the output of the parser (with a suitable program ! 2783: section) is ! 2784: .P{ ! 2785: 2 1 1 ! 2786: .P} ! 2787: Whatever happened to the minus operators? ! 2788: The problem can be traced to the preference for shift in a shift/reduce ! 2789: conflict, which makes ! 2790: .CW - ! 2791: right associative, and gives ! 2792: .CW \en ! 2793: higher precedence than ! 2794: .CW - . ! 2795: .KF ! 2796: .EQ ! 2797: delim off ! 2798: .EN ! 2799: .nf ! 2800: \s5\l'\n(LLu\&\(ul'\s0 ! 2801: .fi ! 2802: .ps 9 ! 2803: .ft CW ! 2804: .PS ! 2805: [ ! 2806: define text % [ ! 2807: boxht = vs ! 2808: B: box $2 invis ! 2809: $1 ljust at B.w ! 2810: ] % ! 2811: ! 2812: boxht = vs ! 2813: ! 2814: C1: [ ! 2815: boxwid = 2; down ! 2816: ! 2817: text("state 0") ! 2818: text(" $accept : .expr $end ") ! 2819: text("", ht vs/3) ! 2820: text(" NUM shift 2") ! 2821: text(" . error") ! 2822: text(" expr goto 1") ! 2823: text("", ht vs/2) ! 2824: text("state 1") ! 2825: text("", ht vs/3) ! 2826: text(" $accept : expr.$end ") ! 2827: text(" expr : expr.\en ") ! 2828: text(" expr : expr.- expr ") ! 2829: text(" $end accept") ! 2830: text(" \en shift 3") ! 2831: text(" - shift 4") ! 2832: text(" . error") ! 2833: text("", ht vs/2) ! 2834: text("state 2") ! 2835: text("", ht vs/3) ! 2836: text(" expr : NUM. (3)") ! 2837: text(" . reduce 3") ! 2838: ] ! 2839: ! 2840: C2: [ ! 2841: boxwid = 2.5; down ! 2842: ! 2843: text("state 3") ! 2844: text(" expr : expr \en. (1)") ! 2845: text("", ht vs/3) ! 2846: text(" . reduce 1") ! 2847: text("", ht vs/2) ! 2848: text("state 4") ! 2849: text(" expr : expr -.expr ") ! 2850: text("", ht vs/3) ! 2851: text(" NUM shift 2") ! 2852: text(" . error") ! 2853: text(" expr goto 5") ! 2854: text("", ht vs/2) ! 2855: .ft CB ! 2856: text("5: conflict (shift \en, reduce 2)") ! 2857: text("5: conflict (shift -, reduce 2)") ! 2858: text("state 5") ! 2859: text(" expr : expr.\en ") ! 2860: text(" expr : expr.- expr ") ! 2861: text(" expr : expr - expr. (2)") ! 2862: text("", ht vs/3) ! 2863: text(" \en shift 3") ! 2864: text(" - shift 4") ! 2865: text(" . reduce 2") ! 2866: .ft CW ! 2867: ] with .ne at C1.nw + pagewid-.75,0 ! 2868: ] ! 2869: .PE ! 2870: .EQ ! 2871: delim $$ ! 2872: .EN ! 2873: .@tag FI _FI.Y.OUTPUT_ ! 2874: .FI _FI.Y.OUTPUT_ ! 2875: A slightly edited ! 2876: .CW y.output ! 2877: file. ! 2878: .EF 0 ! 2879: .nf ! 2880: \s5\l'\n(LLu\&\(ul'\s0 ! 2881: .fi ! 2882: .SP ! 2883: .KE ! 2884: .PP ! 2885: A slightly edited version of the ! 2886: .CW y.output ! 2887: file for this grammar appears in Figure _FI.Y.OUTPUT_. ! 2888: The 2 shift/reduce conflicts are in state 5. ! 2889: In this state, ! 2890: by default, the parser shifts the lookahead symbols ! 2891: .CW \en ! 2892: and ! 2893: .CW - ! 2894: instead of using the item ! 2895: .P{ ! 2896: expr : expr - expr. (2) ! 2897: .P} ! 2898: to reduce by production (2). ! 2899: A reduction occurs only when a right side is at the top of the ! 2900: parser stack, so the stack must contain states corresponding to ! 2901: .P{ ! 2902: \f1$...$\fP expr$"" sub a$ - expr$"" sub b$ ! 2903: .P} ! 2904: (The subscripts merely distinguish between the ! 2905: two occurrences of ! 2906: .CW expr .) ! 2907: .PP ! 2908: The other items in state 5 tell us more about the choices ! 2909: faced by the parser. ! 2910: With lookahead ! 2911: .CW \en ! 2912: the parser shifts, by default. ! 2913: Thus, it treats ! 2914: .CW expr$"" sub b$ ! 2915: on top of the stack as if it were in the item ! 2916: .P{ ! 2917: expr : expr$"" sub b$.\en ! 2918: .P} ! 2919: instead of the item ! 2920: .P{ ! 2921: expr : expr$"" sub a$ - expr$"" sub b$. (2) ! 2922: .P} ! 2923: Similarly, with lookahead ! 2924: .CW - , ! 2925: the parser treats ! 2926: .CW expr$"" sub b$ ! 2927: as if it were the first subexpression in ! 2928: .P{ ! 2929: expr : expr$"" sub b$.- expr ! 2930: .P} ! 2931: .PP ! 2932: Putting these observations together, the input ! 2933: .CW 2-1-1\en ! 2934: will result in the stack eventually containing ! 2935: .P{ ! 2936: expr - expr - expr \en ! 2937: .P} ! 2938: .PP ! 2939: Now, when the right side ! 2940: .CW expr$^$\en ! 2941: is reduced, its action will print a newline and return, ! 2942: abandoning the parse in midstream. ! 2943: .PP ! 2944: The addition of the precedence declarations ! 2945: .P{ ! 2946: %nonassoc '\en' ! 2947: %left '-' ! 2948: .P} ! 2949: eliminates the conflicts in state 5, resulting in the ! 2950: new state ! 2951: .P{ ! 2952: state 5 ! 2953: expr : expr.\en ! 2954: expr : expr.- expr ! 2955: expr : expr - expr. (2) ! 2956: .sp .5 ! 2957: . reduce 2 ! 2958: .P} ! 2959: Here, the reduction takes precedence over the potential shifts, ! 2960: thereby implementing the left associativity of ! 2961: .CW - ! 2962: and its higher precedence over ! 2963: .CW \en . ! 2964: .SS "Precedence Declarations" ! 2965: Precedence declarations give rise to disambiguating ! 2966: rules for resolving parsing conflicts. ! 2967: As mentioned in Section _SH2_, a precedence declaration ! 2968: starts with ! 2969: .CW %left , ! 2970: .CW %right , ! 2971: or ! 2972: .CW %nonassoc . ! 2973: These keywords specify the associativity of the tokens in a declaration. ! 2974: All the tokens in a declaration have the same precedence; tokens ! 2975: in successive declarations have higher precedence. ! 2976: A token in a precedence declaration need not be, but can be, ! 2977: declared by ! 2978: .CW %token ! 2979: as well. ! 2980: .PP ! 2981: The disambiguating rules are as follows. ! 2982: .SP .5 ! 2983: .IP 1. 4 ! 2984: Although declared only for tokens and literals, precedence ! 2985: information is attached to each production as well. ! 2986: The precedence and associativity of a production ! 2987: is that of the last token or literal ! 2988: on its right side. ! 2989: The ! 2990: .CW %prec ! 2991: construction overrides this default. ! 2992: .SP .5 ! 2993: .IP 2. ! 2994: If there is a shift/reduce conflict, and both ! 2995: the lookahead symbol (to be shifted) ! 2996: and the production (to be reduced) ! 2997: have precedence declarations, then ! 2998: the conflict is resolved in favor of the action (shift or reduce) ! 2999: with the higher precedence. ! 3000: If the precedences are the same, then the associativity is used; ! 3001: left associative implies reduce, right associative ! 3002: implies shift, and nonassociative implies error. ! 3003: .SP .5 ! 3004: .IP 3. ! 3005: In the absence of precedence information, the default ! 3006: disambiguating rules given earlier in this section are used. ! 3007: More precisely, suppose that there is no ! 3008: precedence information for either the lookahead symbol or ! 3009: a production to be reduced by. ! 3010: A shift/reduce conflict is resolved by shifting. ! 3011: A reduce/reduce conflict is resolved by reducing by the ! 3012: production that appears earlier in the specification. ! 3013: Conflicts resolved by these default rules are reported. ! 3014: .SP .5 ! 3015: .LP ! 3016: Conflicts resolved by precedence are not counted in the shift/reduce ! 3017: and reduce/reduce conflicts reported by Yacc. ! 3018: Thus, mistakes in precedence declarations can mask errors in ! 3019: the design of the productions. ! 3020: .SS "Shift a Dangling Else" ! 3021: As an example of the power of the default disambiguating rules ! 3022: consider a fragment from a programming language involving an ! 3023: if-then-else construction: ! 3024: .P{ ! 3025: stmt : IF '(' expr ')' stmt ! 3026: | IF '(' expr ')' stmt ELSE stmt ! 3027: ; ! 3028: .P} ! 3029: Here, ! 3030: .CW IF ! 3031: and ! 3032: .CW ELSE ! 3033: are tokens, ! 3034: .CW stmt ! 3035: is a nonterminal for statements, and ! 3036: .CW expr ! 3037: is a nonterminal for expressions. ! 3038: Call the first production the ! 3039: .I "simple-if" ! 3040: production and the second the ! 3041: .I "else-if" ! 3042: production. ! 3043: .PP ! 3044: These two productions are ambiguous, since ! 3045: .P{ ! 3046: IF ( expr$"" sub 1$ ) IF ( expr$"" sub 2$ ) stmt$"" sub a$ ELSE stmt$"" sub b$ ! 3047: .P} ! 3048: can be structured in two ways ! 3049: .ft CW ! 3050: .TS ! 3051: lw4 0 l7 | l. ! 3052: IF ( expr$"" sub 1$ ) { IF ( expr$"" sub 1$ ) { ! 3053: .ft CB ! 3054: IF ( expr$"" sub 2$ ) stmt$"" sub a$ IF ( expr$"" sub 2$ ) stmt$"" sub a$ ! 3055: \f(CW}\fP ELSE stmt$"" sub b$ ! 3056: .ft CW ! 3057: ELSE stmt$"" sub b$ } ! 3058: .TE ! 3059: .LP ! 3060: The second interpretation, with an ! 3061: .CW ELSE ! 3062: matching the nearest preceding unmatched ! 3063: .CW IF , ! 3064: is the one taken by most programming languages. ! 3065: It is the interpretation obtained when shift/reduce conflicts are ! 3066: resolved in favor of shift actions. ! 3067: .PP ! 3068: The ! 3069: .CW y.output ! 3070: file for a grammar containing the simple-if and if-else productions ! 3071: contains a shift/reduce conflict, illustrated by ! 3072: .P{ ! 3073: .ft CW ! 3074: 8: shift/reduce conflict (shift 9, red'n 1) on ELSE ! 3075: .ft CB ! 3076: state 8 ! 3077: stmt : IF ( expr ) stmt. (1) ! 3078: stmt : IF ( expr ) stmt.ELSE stmt ! 3079: .ft CW ! 3080: .sp .5 ! 3081: ELSE shift 9 ! 3082: . reduce 1 ! 3083: .P} ! 3084: This conflict occurs when the lookahead symbol is ! 3085: .CW ELSE ! 3086: and the parser stack contains the right side of the simple-if production ! 3087: .P{ ! 3088: \f1$...$\fP IF ( expr ) stmt ! 3089: .P} ! 3090: The parser chooses to shift the ! 3091: .CW ELSE ! 3092: rather than reduce by the simple-if production. ! 3093: This choice allows ! 3094: .P{ ! 3095: \f1$...$\fP IF ( expr ) stmt ELSE stmt ! 3096: .P} ! 3097: to be successfully reduced by the if-else production. ! 3098: Note that a premature application of the simple-if rule ! 3099: (with lookahead ! 3100: .CW ELSE ) ! 3101: would lead to the stack contents ! 3102: .P{ ! 3103: \f1$...$\fP stmt ELSE stmt ! 3104: .P} ! 3105: which cannot be parsed further. ! 3106: .PP ! 3107: A shift on lookahead ! 3108: .CW ELSE ! 3109: also matches an ! 3110: .CW ELSE ! 3111: with the nearest preceding unmatched ! 3112: .CW IF . ! 3113: With stack contents ! 3114: .P{ ! 3115: \f1$...$\fP \f(CWIF ( expr )\fP IF ( expr ) stmt ! 3116: .P} ! 3117: and lookahead ! 3118: .CW ELSE , ! 3119: the parser shifts, so the stack eventually holds ! 3120: .P{ ! 3121: \f1$...$\fP \f(CWIF ( expr )\fP IF ( expr ) stmt ELSE stmt ! 3122: .P} ! 3123: A reduction by the if-else production now yields ! 3124: .P{ ! 3125: \f1$...$\fP \f(CWIF ( expr )\fP stmt ! 3126: .P} ! 3127: which can be reduced by the simple-if production. ! 3128: .@tag SH _SH5_ ! 3129: .SH _SH5_ "Error Handling" ! 3130: Error handling is an extremely difficult area, and many of the problems are ! 3131: semantic ones. ! 3132: When an error is found, it may be necessary to undo the effect of ! 3133: actions\(emfor example, to reclaim parse-tree storage, to delete or alter ! 3134: symbol-table entries\(emand, typically, set flags to avoid generation of ! 3135: further output. ! 3136: .PP ! 3137: It is seldom acceptable to stop all processing when an error is found; ! 3138: further syntax errors might be found if parsing continues. ! 3139: But, how do we get the parser ``restarted'' after an error is detected. ! 3140: One approach is to discard tokens from the input until parsing can be ! 3141: continued. ! 3142: .PP ! 3143: Yacc provides a simple, but reasonably general, feature for discarding ! 3144: tokens. ! 3145: The token name ! 3146: .CW error ! 3147: is reserved for error handling. ! 3148: On the right side of a production, ! 3149: .CW error ! 3150: suggests a place where error recovery is planned. ! 3151: When an error occurs, the parser pops its stack until it enters a ! 3152: state where the token ! 3153: .CW error ! 3154: is legal. ! 3155: It then behaves as if ! 3156: .CW error ! 3157: were the current lookahead, and performs the action encountered. ! 3158: The lookahead is then reset to the token that caused the error. ! 3159: If no error productions are specified, parsing halts when an ! 3160: error is detected. ! 3161: .PP ! 3162: In order to prevent a cascade of error messages, the parser, after ! 3163: detecting an error, remains in the error state until ! 3164: three tokens have been successfully ! 3165: read and shifted. ! 3166: If an error is detected when the parser is already in error state, ! 3167: no message is given, and the input token is quietly deleted. ! 3168: .PP ! 3169: For example, a production ! 3170: .P{ ! 3171: stmt : error ! 3172: .P} ! 3173: would, in effect, mean that on a syntax error ! 3174: the parser would attempt to skip over the statement ! 3175: in which the error was seen. ! 3176: More precisely, the parser will ! 3177: scan ahead, looking for three tokens that might legally follow ! 3178: a statement, and start processing at the first of these; if ! 3179: the beginnings of statements are not sufficiently distinctive, it may make a ! 3180: false start in the middle of a statement, and end up reporting a ! 3181: second error where there is in fact no error. ! 3182: .PP ! 3183: Actions can be used with these special error rules. ! 3184: These actions might attempt to reinitialize tables, reclaim symbol table space, etc. ! 3185: .PP ! 3186: Productions with just ! 3187: .CW error ! 3188: on the right side are very general, but difficult to control. ! 3189: Somewhat easier are productions such as ! 3190: .P{ ! 3191: stmt : error ';' ! 3192: .P} ! 3193: Here, upon error, the parser attempts to skip over the statement, but ! 3194: will do so by skipping to the next semicolon ! 3195: All tokens after the error and before the next semicolon ! 3196: cannot be shifted, and are discarded. ! 3197: When the semicolon is seen, this right side will be reduced, ! 3198: and any ``cleanup'' ! 3199: action associated with it performed. ! 3200: .PP ! 3201: Another form of error production arises in interactive applications, where ! 3202: it may be desirable to permit a line to be reentered after an error. ! 3203: A possible error production might be ! 3204: .EQ ! 3205: delim off ! 3206: .EN ! 3207: .P{ ! 3208: input : error '\en' ! 3209: { printf("Reenter last line: "); } ! 3210: input ! 3211: { $$ = $input; } ! 3212: ; ! 3213: .P} ! 3214: One potential difficulty with this approach is that ! 3215: the parser must correctly process three input tokens before it ! 3216: admits that it has correctly resynchronized after the error. ! 3217: If the reentered line contains an error ! 3218: in the first two tokens, the parser deletes the offending tokens, ! 3219: and gives no message; this is clearly unacceptable. ! 3220: For this reason, there is a mechanism that ! 3221: can be used to force the parser ! 3222: to believe that an error has been fully recovered from. ! 3223: The statement ! 3224: .P{ ! 3225: yyerrok; ! 3226: .P} ! 3227: in an action ! 3228: resets the parser to its normal mode. ! 3229: The last example is better written ! 3230: .P{ ! 3231: input : error '\en' ! 3232: { yyerrok; printf("Reenter last line: "); } ! 3233: input ! 3234: { $$ = $input; } ! 3235: ; ! 3236: .P} ! 3237: .EQ ! 3238: delim $$ ! 3239: .EN ! 3240: .PP ! 3241: As mentioned above, the token seen immediately ! 3242: after the ! 3243: .CW error ! 3244: symbol is the input token at which the ! 3245: error was discovered. ! 3246: Sometimes, this is inappropriate; for example, an ! 3247: error recovery action might ! 3248: take upon itself the job of finding the correct place to resume input. ! 3249: In this case, ! 3250: the previous lookahead token must be cleared. ! 3251: The statement ! 3252: .P{ ! 3253: yyclearin; ! 3254: .P} ! 3255: in an action has this effect. ! 3256: For example, suppose the action after error ! 3257: is to call some sophisticated resynchronization routine, ! 3258: supplied by the user, that attempts to advance the input to the ! 3259: beginning of the next valid statement. ! 3260: After this routine is called, the next token returned by ! 3261: .CW yylex ! 3262: is presumably the first token in a legal statement; ! 3263: the old, illegal token must be discarded, and the error state reset. ! 3264: This can be done by a rule like ! 3265: .P{ ! 3266: stmt : error ! 3267: { resynch(); yyerrok; yyclearin; } ! 3268: ; ! 3269: .P} ! 3270: .PP ! 3271: These mechanisms are admittedly crude, but do allow for a simple, ! 3272: fairly effective recovery of the parser ! 3273: from many errors; ! 3274: moreover, the user can get control to deal with ! 3275: the error actions required by other portions of the program. ! 3276: .@tag SH _SH6_ ! 3277: .SH _SH6_ "The Yacc Environment" ! 3278: From a specification, Yacc creates a file of C programs, called ! 3279: .CW y.tab.c ! 3280: on most systems. ! 3281: .SS "Program Organization" ! 3282: User-code in a specification file ! 3283: .P{ ! 3284: %{ ! 3285: $<!$\f2user supplied code within declarations\fP$>!$ ! 3286: #define YYSTYPE $<!$\f1desired type\fP$>!$ ! 3287: %} ! 3288: $<!$\f2declarations section\fP$>!$ ! 3289: %% ! 3290: $<!$\f2productions\fP$>!$ ! 3291: %% ! 3292: $<!$ \f1program section\fP$>!$ ! 3293: .P} ! 3294: leads to a ! 3295: .CW y.tab.c ! 3296: file organized as follows: ! 3297: .P{ ! 3298: $<!$\&\f2user supplied code within declarations\fP$>!$ ! 3299: #define YYSTYPE $<!$\f1desired type\fP$>!$ ! 3300: $<!$\f2token and other declarations\fP$>!$ ! 3301: $<!$\f2program section\fP$>!$ ! 3302: $<!$\f2parser tables\fP$>!$ ! 3303: yyparse() { \&\f1$...$\fP } ! 3304: .P} ! 3305: Actions are incorporated into ! 3306: .CW yyparse . ! 3307: .PP ! 3308: As mentioned in Section _SH1_, ! 3309: .CW yyparse , ! 3310: the code for the parser, expects the following functions ! 3311: to be supplied: ! 3312: .P{ ! 3313: int yylex() { ! 3314: \f2a lexical analyzer; returns a token\fP ! 3315: } ! 3316: int main(\f1$...$\fP) { ! 3317: \f1$...$\fP yyparse(); \f1$...$\fP ! 3318: } ! 3319: void yyerror(s) char *s; { ! 3320: \f2print an error message pointed to by\fP s ! 3321: } ! 3322: .P} ! 3323: .PP ! 3324: The function ! 3325: .CW main ! 3326: decides when it wants to call ! 3327: .CW yyparse , ! 3328: which returns 0 if the parser accepts, and 1 if an error is detected ! 3329: and no error recovery is possible. ! 3330: .PP ! 3331: A user-supplied function ! 3332: .CW yyerror ! 3333: is called with a string containing an error message. ! 3334: The average application will want to do more than simply print the ! 3335: message; for example, the message might be ! 3336: accompanied by the input line number on which the error was detected. ! 3337: The external integer variable ! 3338: .CW yychar ! 3339: contains the lookahead token number at the time an error is ! 3340: detected; this may be of some interest in giving better ! 3341: diagnostics. ! 3342: .PP ! 3343: The external variable ! 3344: .CW yydebug ! 3345: is normally set to 0. ! 3346: It it is set to a nonzero value, the parser will output a ! 3347: verbose description of its actions, including the tokens ! 3348: read and the parser actions. ! 3349: Depending on the operating environment, it may be possible ! 3350: to set this variable by using a debugging system. ! 3351: .SS "Lexical Tie-Ins" ! 3352: The lexical analyzer ! 3353: .CW yylex ! 3354: must return an integer, the token number, representing ! 3355: the lookahead token. ! 3356: An attribute value associated with the token must be ! 3357: placed in the global variable ! 3358: .CW yylval . ! 3359: .PP ! 3360: The parser and the lexical analyzer must agree on the ! 3361: token numbers in order for communication between them to ! 3362: take place. ! 3363: Token numbers may be chosen by Yacc, or chosen by the user. ! 3364: In either case, the ! 3365: .CW #def\&ine ! 3366: mechanism of C is used to allow the lexical analyzer ! 3367: to refer to these numbers symbolically. ! 3368: For example, the declarations section ! 3369: .P{ ! 3370: %token IF ELSE ! 3371: .P} ! 3372: leads to the following definitions in the file ! 3373: .CW y.tab.c : ! 3374: .P{ ! 3375: # define IF 257 ! 3376: # define ELSE 258 ! 3377: .P} ! 3378: .PP ! 3379: If ! 3380: .CW yylex ! 3381: is included in the programs section, it is within the scope ! 3382: of these definitions, so ! 3383: .CW IF ! 3384: and ! 3385: .CW ELSE ! 3386: can be used as the names of token numbers in ! 3387: .CW yylex . ! 3388: .PP ! 3389: A file ! 3390: .CW y.tab.h ! 3391: containing the definition of token numbers can be ! 3392: created by running Yacc with the ! 3393: .CW -d ! 3394: option. ! 3395: .PP ! 3396: The approach of treating token names as defined constants ! 3397: leads to clear, easily modified lexical analyzers; the only ! 3398: pitfall is the need to avoid using any token names that are ! 3399: reserved or significant in C or the parser. ! 3400: For example, the use of the token names ! 3401: .CW if ! 3402: and ! 3403: .CW while ! 3404: will almost certainly cause severe difficulties when ! 3405: the lexical analyzer is compiled. ! 3406: The token name ! 3407: .CW error ! 3408: is reserved for error handling; see Section _SH5_. ! 3409: .PP ! 3410: Yacc chooses token numbers if the user does not. ! 3411: The default token number for a literal character ! 3412: is the numerical value of the character in the ! 3413: local character set. ! 3414: Other names are assigned token numbers starting at ! 3415: 257. ! 3416: .PP ! 3417: To assign a number to a token (including a literal), the first ! 3418: appearance of the token name or literal in the declarations section ! 3419: can be immediately followed by a nonnegative integer. ! 3420: This integer is taken to be the token number of the name or literal. ! 3421: Names and literals not defined by this mechanism retain their default ! 3422: definition. ! 3423: It is important that all token numbers be distinct. ! 3424: .PP ! 3425: For historical reasons, the endmarker must have token number ! 3426: 0 or negative. ! 3427: This token number cannot be redefined by the user; ! 3428: thus, all lexical analyzers must be prepared to return ! 3429: 0 or negative as a token number upon reaching the end of ! 3430: their input. ! 3431: .SS "Communicating Context to the Lexical Analyzer" ! 3432: Some lexical decisions depend on context. ! 3433: For example, the lexical analyzer might want to ! 3434: delete blanks normally, but not within quoted strings. ! 3435: Or names might be entered into a symbol table in declarations, ! 3436: but not in expressions. ! 3437: .PP ! 3438: One way of handling this situation is ! 3439: to create a global flag that is ! 3440: examined by the lexical analyzer, and set by actions. ! 3441: For example, suppose a program ! 3442: consists of zero or more declarations, ! 3443: followed by zero or more statements. ! 3444: Consider: ! 3445: .P{ ! 3446: %{ ! 3447: int dflag; ! 3448: %} ! 3449: \&\f2$...$ other declarations $...$\f(CB ! 3450: %% ! 3451: prog : decls stmts ! 3452: ; ! 3453: decls : /* empty */ { dflag = 1; } ! 3454: | decls declaration ! 3455: ; ! 3456: stmts : /* empty */ { dflag = 0; } ! 3457: | stmts statement ! 3458: ; ! 3459: \&\f2$...$ other productions $...$\f(CB ! 3460: .P} ! 3461: .PP ! 3462: The flag ! 3463: .CW dflag ! 3464: is now 1 when reading declarations and 0 when reading statements, ! 3465: .ul ! 3466: except for the first token in the first statement. ! 3467: This token must be seen by the parser before it can tell that ! 3468: the declarations have ended and the productions have ! 3469: begun. ! 3470: In many cases, this single token exception does not ! 3471: affect the lexical scan. ! 3472: .PP ! 3473: This kind of ``backdoor'' approach can be elaborated ! 3474: to a noxious degree. ! 3475: Nevertheless, it represents a way of doing some things ! 3476: that are difficult, if not impossible, to ! 3477: do otherwise. ! 3478: .PP ! 3479: Some programming languages ! 3480: permit the user to ! 3481: use words like ! 3482: .CW if , ! 3483: which are normally reserved, ! 3484: as label or variable names, provided that such use does not ! 3485: conflict with the legal use of these names in the programming language. ! 3486: This is extremely hard to do in the framework of Yacc; ! 3487: it is difficult to pass information to the lexical analyzer ! 3488: telling it ``this instance of ! 3489: .CW if ! 3490: is a keyword, and that instance is a variable''. ! 3491: The user can make a stab at it, using flags like ! 3492: .CW dflag , ! 3493: above, but it is difficult. ! 3494: It is better that the keywords be ! 3495: .I reserved ; ! 3496: that is, be forbidden for use as variable names. ! 3497: There are powerful stylistic reasons for preferring this, anyway. ! 3498: .SS "Support for Arbitrary Attribute Types" ! 3499: By default, the values returned by actions and ! 3500: the lexical analyzer are integers. ! 3501: Other types can be supported by defining ! 3502: .CW YYSTYPE ! 3503: in the declarations section, as in ! 3504: .P{ ! 3505: %{ ! 3506: #define YYSTYPE double ! 3507: %} ! 3508: .P} ! 3509: .CW YYSTYPE ! 3510: is not a normal variable, because the parser contains the following ! 3511: lines to define it to be ! 3512: .CW int ! 3513: if it has not already been defined by the user: ! 3514: .P{ ! 3515: #ifndef YYSTYPE ! 3516: #define YYSTYPE int ! 3517: #endif ! 3518: .P} ! 3519: .PP ! 3520: Clearly, ! 3521: .CW YYSTYPE ! 3522: can be defined to be any type, including a union type. ! 3523: .PP ! 3524: The ! 3525: .CW %union ! 3526: mechanism of Yacc attempts to make the underlying union ! 3527: transparent, in all but a few places where Yacc needs ! 3528: help in determining which field of the union is intended. ! 3529: .PP ! 3530: Unions are declared in the declarations section, an example being ! 3531: .P{ ! 3532: %union { ! 3533: int ival; ! 3534: double dval; ! 3535: char * sval; ! 3536: } ! 3537: .P} ! 3538: A union type with these members is created for the Yacc value stack, ! 3539: and for the global variables ! 3540: .CW yylval ! 3541: and ! 3542: .CW yyval . ! 3543: With the ! 3544: .CW -d ! 3545: option, Yacc copies the union type into the ! 3546: .CW y.tab.h ! 3547: file. ! 3548: The type of the union can be referred to as ! 3549: .CW YYSTYPE . ! 3550: .PP ! 3551: The type of each attribute must now correspond to one of ! 3552: the union members. ! 3553: The construction ! 3554: .P{ ! 3555: <name> ! 3556: .P} ! 3557: indicates a union member name. ! 3558: If the construction follows ! 3559: .CW %token , ! 3560: .CW %left , ! 3561: .CW %right , ! 3562: or ! 3563: .CW %nonassoc , ! 3564: then the union member name is associated with the tokens in ! 3565: that declaration. ! 3566: Another keyword ! 3567: .CW %type ! 3568: is used similarly to associate union member names with nonterminals. ! 3569: Thus, we might use ! 3570: .P{ ! 3571: %type <dval> expr term ! 3572: .P} ! 3573: .EQ ! 3574: delim off ! 3575: .EN ! 3576: .PP ! 3577: There remain a couple of cases where these mechanisms are insufficient. ! 3578: If there is an action within a rule, the value returned ! 3579: by this action has no a priori type. ! 3580: Similarly, reference to left context values ! 3581: leaves Yacc with no easy way of knowing the type. ! 3582: In this case, a type can be imposed on the reference by inserting ! 3583: a union member name, between ! 3584: .CW < ! 3585: and ! 3586: .CW > , immediately after ! 3587: the first ! 3588: .CW $ . ! 3589: An example of this usage is ! 3590: .P{ ! 3591: rule : aaa { $<intval>$ = 3; } ! 3592: bbb { fun( $<intval>2, $<other>0 ); } ! 3593: ; ! 3594: .P} ! 3595: This syntax has little to recommend it, but the situation arises rarely. ! 3596: .PP ! 3597: The facilities in this subsection are not triggered until they are used: ! 3598: in particular, the use of ! 3599: .CW %type ! 3600: will turn on these mechanisms. ! 3601: When they are used, there is a fairly strict level of checking. ! 3602: For example, use of ! 3603: .CW $\f2n\fP ! 3604: or ! 3605: .CW $$ ! 3606: to refer to something with no defined type ! 3607: is diagnosed. ! 3608: If these facilities are not triggered, the Yacc value stack is used to ! 3609: hold ! 3610: .CW int s, ! 3611: as was true historically. ! 3612: .EQ ! 3613: delim $$ ! 3614: .EN ! 3615: .NH 1 ! 3616: References ! 3617: .LP ! 3618: |reference_placement
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.