|
|
1.1 ! root 1: .\" @(#)ss2 6.1 (Berkeley) 5/8/86 ! 2: .\" ! 3: .SH ! 4: 2: Actions ! 5: .PP ! 6: With each grammar rule, the user may associate actions to be performed each time ! 7: the rule is recognized in the input process. ! 8: These actions may return values, and may obtain the values returned by previous ! 9: actions. ! 10: Moreover, the lexical analyzer can return values ! 11: for tokens, if desired. ! 12: .PP ! 13: An action is an arbitrary C statement, and as such can do ! 14: input and output, call subprograms, and alter ! 15: external vectors and variables. ! 16: An action is specified by ! 17: one or more statements, enclosed in curly braces ``{'' and ``}''. ! 18: For example, ! 19: .DS ! 20: A : \'(\' B \')\' ! 21: { hello( 1, "abc" ); } ! 22: .DE ! 23: and ! 24: .DS ! 25: XXX : YYY ZZZ ! 26: { printf("a message\en"); ! 27: flag = 25; } ! 28: .DE ! 29: are grammar rules with actions. ! 30: .PP ! 31: To facilitate easy communication between the actions and the parser, the action statements are altered ! 32: slightly. ! 33: The symbol ``dollar sign'' ``$'' is used as a signal to Yacc in this context. ! 34: .PP ! 35: To return a value, the action normally sets the ! 36: pseudo-variable ``$$'' to some value. ! 37: For example, an action that does nothing but return the value 1 is ! 38: .DS ! 39: { $$ = 1; } ! 40: .DE ! 41: .PP ! 42: To obtain the values returned by previous actions and the lexical analyzer, the ! 43: action may use the pseudo-variables $1, $2, . . ., ! 44: which refer to the values returned by the ! 45: components of the right side of a rule, reading from left to right. ! 46: Thus, if the rule is ! 47: .DS ! 48: A : B C D ; ! 49: .DE ! 50: for example, then $2 has the value returned by C, and $3 the value returned by D. ! 51: .PP ! 52: As a more concrete example, consider the rule ! 53: .DS ! 54: expr : \'(\' expr \')\' ; ! 55: .DE ! 56: The value returned by this rule is usually the value of the ! 57: .I expr ! 58: in parentheses. ! 59: This can be indicated by ! 60: .DS ! 61: expr : \'(\' expr \')\' { $$ = $2 ; } ! 62: .DE ! 63: .PP ! 64: By default, the value of a rule is the value of the first element in it ($1). ! 65: Thus, grammar rules of the form ! 66: .DS ! 67: A : B ; ! 68: .DE ! 69: frequently need not have an explicit action. ! 70: .PP ! 71: In the examples above, all the actions came at the end of their rules. ! 72: Sometimes, it is desirable to get control before a rule is fully parsed. ! 73: Yacc permits an action to be written in the middle of a rule as well ! 74: as at the end. ! 75: This rule is assumed to return a value, accessible ! 76: through the usual \$ mechanism by the actions to ! 77: the right of it. ! 78: In turn, it may access the values ! 79: returned by the symbols to its left. ! 80: Thus, in the rule ! 81: .DS ! 82: A : B ! 83: { $$ = 1; } ! 84: C ! 85: { x = $2; y = $3; } ! 86: ; ! 87: .DE ! 88: the effect is to set ! 89: .I x ! 90: to 1, and ! 91: .I y ! 92: to the value returned by C. ! 93: .PP ! 94: Actions that do not terminate a rule are actually ! 95: handled by Yacc by manufacturing a new nonterminal ! 96: symbol name, and a new rule matching this ! 97: name to the empty string. ! 98: The interior action is the action triggered off by recognizing ! 99: this added rule. ! 100: Yacc actually treats the above example as if ! 101: it had been written: ! 102: .DS ! 103: $ACT : /* empty */ ! 104: { $$ = 1; } ! 105: ; ! 106: ! 107: A : B $ACT C ! 108: { x = $2; y = $3; } ! 109: ; ! 110: .DE ! 111: .PP ! 112: In many applications, output is not done directly by the actions; ! 113: rather, a data structure, such as a parse tree, is constructed in memory, ! 114: and transformations are applied to it before output is generated. ! 115: Parse trees are particularly easy to ! 116: construct, given routines to build and maintain the tree ! 117: structure desired. ! 118: For example, suppose there is a C function ! 119: .I node , ! 120: written so that the call ! 121: .DS ! 122: node( L, n1, n2 ) ! 123: .DE ! 124: creates a node with label L, and descendants n1 and n2, and returns the index of ! 125: the newly created node. ! 126: Then parse tree can be built by supplying actions such as: ! 127: .DS ! 128: expr : expr \'+\' expr ! 129: { $$ = node( \'+\', $1, $3 ); } ! 130: .DE ! 131: in the specification. ! 132: .PP ! 133: The user may define other variables to be used by the actions. ! 134: Declarations and definitions can appear in ! 135: the declarations section, ! 136: enclosed in the marks ``%{'' and ``%}''. ! 137: These declarations and definitions have global scope, ! 138: so they are known to the action statements and the lexical analyzer. ! 139: For example, ! 140: .DS ! 141: %{ int variable = 0; %} ! 142: .DE ! 143: could be placed in the declarations section, ! 144: making ! 145: .I variable ! 146: accessible to all of the actions. ! 147: The Yacc parser uses only names beginning in ``yy''; ! 148: the user should avoid such names. ! 149: .PP ! 150: In these examples, all the values are integers: a discussion of ! 151: values of other types will be found in Section 10.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.