Annotation of researchv10dc/vol2/yacc/yacc.ms, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.