Intel XENIX 286 Programmers Guide (86) - Tenox.tc
Intel XENIX 286 Programmers Guide (86) - Tenox.tc Intel XENIX 286 Programmers Guide (86) - Tenox.tc
XENIX Programming yacc: Compiler-Compiler It could then apply the rule to the rightmost three sy mbols, reducing them to expr and leaving expr - expr Now the rule can be reduced once more; the effect is to take the right associative interpretation. Thus, having read expr - expr the parser can do two legal things, a shift or a reduction, and has no way of deciding between them. This is called a shift/reduce conflict. It may also happen that the parser has a choice of two legal reductions; this is called a reduce/reduce conflict. Note that there are never any shift/shift conflicts. When there are shift/reduce or reduce/reduce conflicts, yacc still produces a parser. It does this by selecting one of the valid steps wherever it has a choice. A rule describing which choice to make in a given situation is called a disambiguating rule. yacc invokes two disambiguating rules by default: 1. In a shift/reduce conflict, the default is to do the shift. 2. In a reduce/reduce conflict, the default is to reduce by the earlier gram mar rule (in the input sequence). Rule 1 implies that reductions are deferred whenever there is a choice, in favor of shifts. Rule 2 gives the user rather crude control over the behavior of the parser in this situation, but reduce/reduce conflicts should be avoided whenever possible. Conflicts may arise because of mistakes in input or logic, or because the grammar rules, while consistent, require a more complex parser than yacc can construct. The use of actions within rules can also cause conflicts, if the action must be done before the parser can be sure which rule is being recognized. In these cases, the application of disambiguating rules is inappropriate and leads to an incorrect parser. For this reason, yacc always reports the number of shift/reduce and reduce/reduce conflicts resolved by Rule 1 and Rule 2. In general, whenever it is possible to apply disambiguating rules to produce a correct parser, it is also possible to rewrite the gram mar rules so that the same inputs are read but there are no conflicts. For this reason, most previous parser generators have considered conflicts to be fatal errors. Our experience has suggested that this rewriting is somewhat unnatural, and produces slower parsers; thus, yacc will produce parsers even in the presence of conflicts. As an example of the power of disambiguating rules, consider a fragment from a programming language involving an if-then-else construction: stat I F I { I cond I ) I stat IF I { I cond I ) I stat ELSE stat 10-15
yacc: Compiler-Compiler XENIX Programming In these rules, IF and ELSE are tokens, cond is a nonterminal sy mbol describing conditional (logical) expressions, and stat is a nonterminal symbol describing statements. The first rule will be called the simple-if rule, and the second the if-else rule. These two rules form an ambiguous construction, since input of the form IF (C1 )IF(C2)51 ELSE 52 can be structured according to these rules in two ways: or IF(C1 ){ IF ( C2 ) 51 } ELSE 52 IF(C1 ) { IF ( C2 ) 51 ELSE 52 } The second interpretation is the one given in most programm ing languages having this construct. Each ELSE is associated with the last IF immediately preceding the ELSE. In this example, consider the situation where the parser has seen I F ( C 1 ) I F ( C2 ) 5 1 and is looking at the ELSE. It can immediately reduce by the simple-if rule to get IF ( C1 ) stat and then read the remaining input ELSE 52 and reduce IF ( C1 ) stat ELSE 52 by the if-else rule. This leads to the first of the above groupings of the input. On the other hand, the ELSE may be shifted, S2 read, and then the right-hand portion of IF ( C 1 ) IF ( C2 ) .S 1 ELSE 52 can be reduced by the if-else rule to get IF ( C1 ) stat which can be reduced by the simple-if rule. This leads to the second of the above groupings of the input, which is usually desired. 10-16
- Page 166 and 167: XENIX Programming csh: C Shell Usin
- Page 168 and 169: XENIX Programming csh: C Shell The
- Page 170 and 171: XENIX Programming csh: C Shell Note
- Page 172 and 173: XENIX Programming switch ( string c
- Page 174 and 175: XENIX Programming csh: C Shell Star
- Page 176 and 177: XENIX Programming csh: C Shell Spec
- Page 178 and 179: CHAPTER 9 lex : LEXICAL ANA LYZER G
- Page 180 and 181: XENIX Programming lex: Lexical Anal
- Page 182 and 183: XENIX Programming lex: Lexical Anal
- Page 184 and 185: XENIX Programming lex: Lexical Anal
- Page 186 and 187: XENIX Programming lex: Lexical Anal
- Page 188 and 189: XENIX Programming lex: Lexical Anal
- Page 190 and 191: XENIX Programming lex: Lexical Anal
- Page 192 and 193: XENIX Programm ing lex: Lexical Ana
- Page 194 and 195: XENIX Programming Specifying Source
- Page 196 and 197: XENIX Programming lex: Lexical Anal
- Page 198 and 199: XENIX Programming lex: Lexical Anal
- Page 200 and 201: XENIX Programming The definitions s
- Page 202 and 203: CHAPTER 10 yacc: COMPILER-COMPILER
- Page 204 and 205: XENIX Programming yacc: Compiler-Co
- Page 206 and 207: XENIX Programming yacc: Compiler-Co
- Page 208 and 209: XENIX Programming yacc: Compiler-Co
- Page 210 and 211: XENIX Programming yacc: Compiler-Co
- Page 212 and 213: XENIX Programming yacc: Compiler-Co
- Page 214 and 215: XENIX Programming yacc: Compiler-Co
- Page 218 and 219: XENIX Programming yacc: Compiler-Co
- Page 220 and 221: XENIX Programming yacc: Compiler-Co
- Page 222 and 223: XENIX Programming yacc: Compiler-Co
- Page 224 and 225: XENIX Programming yacc: Compiler-Co
- Page 226 and 227: XENIX Programming yacc: Compiler-Co
- Page 228 and 229: XENIX Programming yacc: Compiler-Co
- Page 230 and 231: XENIX Programming yacc: Compiler-Co
- Page 232 and 233: XENIX Programming yacc: Compiler-Co
- Page 234 and 235: XENIX Programming yacc: Compiler-Co
- Page 236 and 237: XENIX Programming %left %left %left
- Page 238 and 239: XENIX Programming I* lexical analys
- Page 240: XENIX Programming yacc: Compiler-Co
- Page 243 and 244: m4: Macro Processor XENIX Programmi
- Page 245 and 246: m4: Macro Processor XENIX Programmi
- Page 247 and 248: m4: Macro Processor XENIX Programm
- Page 249 and 250: m4: Macro Processor XENIX Programmi
- Page 251 and 252: m4: Macro Processor XENIX Programmi
- Page 253 and 254: C Language Portability XENIX Progra
- Page 255 and 256: C Language Portability XENIX Progra
- Page 257 and 258: C Language Portability XENIX Progra
- Page 259 and 260: C Language Portability XENIX Progra
- Page 261 and 262: C Language Portability XENIX Progra
- Page 263 and 264: C Language Portability XENIX Progra
<strong>XENIX</strong> Programming yacc: Compiler-Compiler<br />
It could then apply the rule to the rightmost three sy mbols, reducing them to expr and<br />
leaving<br />
expr - expr<br />
Now the rule can be reduced once more; the effect is to take the right associative<br />
interpretation. Thus, having read<br />
expr - expr<br />
the parser can do two legal things, a shift or a reduction, and has no way of deciding<br />
between them. This is called a shift/reduce conflict. It may also happen that the parser<br />
has a choice of two legal reductions; this is called a reduce/reduce conflict. Note that<br />
there are never any shift/shift conflicts.<br />
When there are shift/reduce or reduce/reduce conflicts, yacc still produces a parser. It<br />
does this by selecting one of the valid steps wherever it has a choice. A rule describing<br />
which choice to make in a given situation is called a disambiguating rule.<br />
yacc invokes two disambiguating rules by default:<br />
1. In a shift/reduce conflict, the default is to do the shift.<br />
2. In a reduce/reduce conflict, the default is to reduce by the earlier gram mar rule<br />
(in the input sequence).<br />
Rule 1 implies that reductions are deferred whenever there is a choice, in favor of<br />
shifts. Rule 2 gives the user rather crude control over the behavior of the parser in this<br />
situation, but reduce/reduce conflicts should be avoided whenever possible.<br />
Conflicts may arise because of mistakes in input or logic, or because the grammar rules,<br />
while consistent, require a more complex parser than yacc can construct. The use of<br />
actions within rules can also cause conflicts, if the action must be done before the<br />
parser can be sure which rule is being recognized. In these cases, the application of<br />
disambiguating rules is inappropriate and leads to an incorrect parser. For this reason,<br />
yacc always reports the number of shift/reduce and reduce/reduce conflicts resolved by<br />
Rule 1 and Rule 2.<br />
In general, whenever it is possible to apply disambiguating rules to produce a correct<br />
parser, it is also possible to rewrite the gram mar rules so that the same inputs are read<br />
but there are no conflicts. For this reason, most previous parser generators have<br />
considered conflicts to be fatal errors. Our experience has suggested that this rewriting<br />
is somewhat unnatural, and produces slower parsers; thus, yacc will produce parsers<br />
even in the presence of conflicts.<br />
As an example of the power of disambiguating rules, consider a fragment from a<br />
programming language involving an if-then-else construction:<br />
stat I F I { I<br />
cond I ) I stat<br />
IF I { I<br />
cond I ) I stat<br />
ELSE stat<br />
10-15