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