|
|
1.1 ! root 1: .\" @(#)ssA 6.1 (Berkeley) 5/8/86 ! 2: .\" ! 3: .SH ! 4: 10: Advanced Topics ! 5: .PP ! 6: This section discusses a number of advanced features ! 7: of Yacc. ! 8: .SH ! 9: Simulating Error and Accept in Actions ! 10: .PP ! 11: The parsing actions of error and accept can be simulated ! 12: in an action by use of macros YYACCEPT and YYERROR. ! 13: YYACCEPT causes ! 14: .I yyparse ! 15: to return the value 0; ! 16: YYERROR causes ! 17: the parser to behave as if the current input symbol ! 18: had been a syntax error; ! 19: .I yyerror ! 20: is called, and error recovery takes place. ! 21: These mechanisms can be used to simulate parsers ! 22: with multiple endmarkers or context-sensitive syntax checking. ! 23: .SH ! 24: Accessing Values in Enclosing Rules. ! 25: .PP ! 26: An action may refer to values ! 27: returned by actions to the left of the current rule. ! 28: The mechanism is simply the same as with ordinary actions, ! 29: a dollar sign followed by a digit, but in this case the ! 30: digit may be 0 or negative. ! 31: Consider ! 32: .DS ! 33: sent : adj noun verb adj noun ! 34: { \fIlook at the sentence\fR . . . } ! 35: ; ! 36: ! 37: adj : THE { $$ = THE; } ! 38: | YOUNG { $$ = YOUNG; } ! 39: . . . ! 40: ; ! 41: ! 42: noun : DOG ! 43: { $$ = DOG; } ! 44: | CRONE ! 45: { if( $0 == YOUNG ){ ! 46: printf( "what?\en" ); ! 47: } ! 48: $$ = CRONE; ! 49: } ! 50: ; ! 51: . . . ! 52: .DE ! 53: In the action following the word CRONE, a check is made that the ! 54: preceding token shifted was not YOUNG. ! 55: Obviously, this is only possible when a great deal is known about ! 56: what might precede the symbol ! 57: .I noun ! 58: in the input. ! 59: There is also a distinctly unstructured flavor about this. ! 60: Nevertheless, at times this mechanism will save a great ! 61: deal of trouble, especially when a few combinations are to ! 62: be excluded from an otherwise regular structure. ! 63: .SH ! 64: Support for Arbitrary Value Types ! 65: .PP ! 66: By default, the values returned by actions and the lexical analyzer are integers. ! 67: Yacc can also support ! 68: values of other types, including structures. ! 69: In addition, Yacc keeps track of the types, and inserts ! 70: appropriate union member names so that the resulting parser will ! 71: be strictly type checked. ! 72: The Yacc value stack (see Section 4) ! 73: is declared to be a ! 74: .I union ! 75: of the various types of values desired. ! 76: The user declares the union, and associates union member names ! 77: to each token and nonterminal symbol having a value. ! 78: When the value is referenced through a $$ or $n construction, ! 79: Yacc will automatically insert the appropriate union name, so that ! 80: no unwanted conversions will take place. ! 81: In addition, type checking commands such as ! 82: .I Lint\| ! 83: .[ ! 84: Johnson Lint Checker 1273 ! 85: .] ! 86: will be far more silent. ! 87: .PP ! 88: There are three mechanisms used to provide for this typing. ! 89: First, there is a way of defining the union; this must be ! 90: done by the user since other programs, notably the lexical analyzer, ! 91: must know about the union member names. ! 92: Second, there is a way of associating a union member name with tokens ! 93: and nonterminals. ! 94: Finally, there is a mechanism for describing the type of those ! 95: few values where Yacc can not easily determine the type. ! 96: .PP ! 97: To declare the union, the user includes in the declaration section: ! 98: .DS ! 99: %union { ! 100: body of union ... ! 101: } ! 102: .DE ! 103: This declares the Yacc value stack, ! 104: and the external variables ! 105: .I yylval ! 106: and ! 107: .I yyval , ! 108: to have type equal to this union. ! 109: If Yacc was invoked with the ! 110: .B \-d ! 111: option, the union declaration ! 112: is copied onto the ! 113: .I y.tab.h ! 114: file. ! 115: Alternatively, ! 116: the union may be declared in a header file, and a typedef ! 117: used to define the variable YYSTYPE to represent ! 118: this union. ! 119: Thus, the header file might also have said: ! 120: .DS ! 121: typedef union { ! 122: body of union ... ! 123: } YYSTYPE; ! 124: .DE ! 125: The header file must be included in the declarations ! 126: section, by use of %{ and %}. ! 127: .PP ! 128: Once YYSTYPE is defined, ! 129: the union member names must be associated ! 130: with the various terminal and nonterminal names. ! 131: The construction ! 132: .DS ! 133: < name > ! 134: .DE ! 135: is used to indicate a union member name. ! 136: If this follows ! 137: one of the ! 138: keywords %token, ! 139: %left, %right, and %nonassoc, ! 140: the union member name is associated with the tokens listed. ! 141: Thus, saying ! 142: .DS ! 143: %left <optype> \'+\' \'\-\' ! 144: .DE ! 145: will cause any reference to values returned by these two tokens to be ! 146: tagged with ! 147: the union member name ! 148: .I optype . ! 149: Another keyword, %type, is ! 150: used similarly to associate ! 151: union member names with nonterminals. ! 152: Thus, one might say ! 153: .DS ! 154: %type <nodetype> expr stat ! 155: .DE ! 156: .PP ! 157: There remain a couple of cases where these mechanisms are insufficient. ! 158: If there is an action within a rule, the value returned ! 159: by this action has no ! 160: .I "a priori" ! 161: type. ! 162: Similarly, reference to left context values (such as $0 \- see the ! 163: previous subsection ) leaves Yacc with no easy way of knowing the type. ! 164: In this case, a type can be imposed on the reference by inserting ! 165: a union member name, between < and >, immediately after ! 166: the first $. ! 167: An example of this usage is ! 168: .DS ! 169: rule : aaa { $<intval>$ = 3; } bbb ! 170: { fun( $<intval>2, $<other>0 ); } ! 171: ; ! 172: .DE ! 173: This syntax has little to recommend it, but the situation arises rarely. ! 174: .PP ! 175: A sample specification is given in Appendix C. ! 176: The facilities in this subsection are not triggered until they are used: ! 177: in particular, the use of %type will turn on these mechanisms. ! 178: When they are used, there is a fairly strict level of checking. ! 179: For example, use of $n or $$ to refer to something with no defined type ! 180: is diagnosed. ! 181: If these facilities are not triggered, the Yacc value stack is used to ! 182: hold ! 183: .I int' s, ! 184: as was true historically.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.