📄 ss5
字号:
.SH5: Ambiguity and Conflicts.PPA set of grammar rules is.I ambiguousif there is some input string that can be structured in two or more different ways.For example, the grammar rule.DSexpr : expr \'\-\' expr.DEis a natural way of expressing the fact that one way of forming an arithmetic expressionis to put two other expressions together with a minus sign between them.Unfortunately, this grammar rule does notcompletely specify the way that all complex inputsshould be structured.For example, if the input is.DSexpr \- expr \- expr.DEthe rule allows this input to be structured as either.DS( expr \- expr ) \- expr.DEor as.DSexpr \- ( expr \- expr ).DE(The first is called.I "left association" ,the second.I "right association" )..PPYacc detects such ambiguities when it is attempting to build the parser.It is instructive to consider the problem that confronts the parser when it isgiven an input such as.DSexpr \- expr \- expr.DEWhen the parser has read the second expr, the input that it has seen:.DSexpr \- expr.DEmatches the right side of the grammar rule above.The parser could.I reducethe input by applying this rule;after applying the rule;the input is reduced to.I expr (theleft side of the rule).The parser would then read the final part of the input:.DS\- expr.DEand again reduce.The effect of this is to take the left associative interpretation..PPAlternatively, when the parser has seen.DSexpr \- expr.DEit could defer the immediate application of the rule, and continue readingthe input until it had seen.DSexpr \- expr \- expr.DEIt could then apply the rule to the rightmost three symbols, reducing them to.I exprand leaving.DSexpr \- expr.DENow the rule can be reduced once more; the effect is totake the right associative interpretation.Thus, having read.DSexpr \- expr.DEthe parser can do two legal things, a shift or a reduction, and has no way ofdeciding between them.This is called a.I "shift / reduce conflict" .It may also happen that the parser has a choice of two legal reductions;this is called a.I "reduce / reduce conflict" .Note that there are never any ``Shift/shift'' conflicts..PPWhen 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 calleda.I "disambiguating rule" ..PPYacc invokes two disambiguating rules by default:.IP 1.In a shift/reduce conflict, the default is to do the shift..IP 2.In a reduce/reduce conflict, the default is to reduce by the.I earliergrammar rule (in the input sequence)..PPRule 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 parserin this situation, but reduce/reduce conflicts should be avoided whenever possible..PPConflicts 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 mustbe 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, Yaccalways reports the number of shift/reduce and reduce/reduce conflicts resolved by Rule 1 and Rule 2..PPIn general, whenever it is possible to apply disambiguating rules to produce a correct parser, it is alsopossible to rewrite the grammar rules so that the same inputs are read but there are noconflicts.For this reason, most previous parser generatorshave 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..PPAs an example of the power of disambiguating rules, consider a fragment from a programminglanguage involving an ``if-then-else'' construction:.DSstat : IF \'(\' cond \')\' stat | IF \'(\' cond \')\' stat ELSE stat ;.DEIn these rules,.I IFand.I ELSEare tokens,.I condis a nonterminal symbol describingconditional (logical) expressions, and.I statis a nonterminal symbol describing statements.The first rule will be called the.ulsimple-ifrule, and thesecond the.ulif-elserule..PPThese two rules form an ambiguous construction, since input of the form.DSIF ( C1 ) IF ( C2 ) S1 ELSE S2.DEcan be structured according to these rules in two ways:.DSIF ( C1 ) { IF ( C2 ) S1 }ELSE S2.DEor.DSIF ( C1 ) { IF ( C2 ) S1 ELSE S2 }.DEThe second interpretation is the one given in most programming languageshaving this construct.Each.I ELSEis associated with the last preceding``un-\fIELSE'\fRd''.I IF .In this example, consider the situation where the parser has seen.DSIF ( C1 ) IF ( C2 ) S1.DEand is looking at the.I ELSE .It can immediatelyreduceby the simple-if rule to get.DSIF ( C1 ) stat.DEand then read the remaining input,.DSELSE S2.DEand reduce.DSIF ( C1 ) stat ELSE S2.DEby the if-else rule.This leads to the first of the above groupings of the input..PPOn the other hand, the.I ELSEmay be shifted,.I S2read, and then the right hand portion of.DSIF ( C1 ) IF ( C2 ) S1 ELSE S2.DEcan be reduced by the if-else rule to get.DSIF ( C1 ) stat.DEwhich can be reduced by the simple-if rule.This leads to the second of the above groupings of the input, whichis usually desired..PPOnce again the parser can do two valid things \- there is a shift/reduce conflict.The application of disambiguating rule 1 tells the parser to shift in this case,which leads to the desired grouping..PPThis shift/reduce conflict arises only when there is a particular current input symbol,.I ELSE ,and particular inputs already seen, such as.DSIF ( C1 ) IF ( C2 ) S1.DEIn general, there may be many conflicts, and each onewill be associated with an input symbol anda set of previously read inputs.The previously read inputs are characterized by thestateof the parser..PPThe conflict messages of Yacc are best understoodby examining the verbose (\fB\-v\fR) option output file.For example, the output corresponding to the aboveconflict state might be:.DS L23: shift/reduce conflict (shift 45, reduce 18) on ELSEstate 23 stat : IF ( cond ) stat\_ (18) stat : IF ( cond ) stat\_ELSE stat ELSE shift 45 . reduce 18.DEThe first line describes the conflict, giving the state and the input symbol.The ordinary state description follows, givingthe grammar rules active in the state, and the parser actions.Recall that the underline marks theportion of the grammar rules which has been seen.Thus in the example, in state 23 the parser has seen input correspondingto.DSIF ( cond ) stat.DEand the two grammar rules shown are active at this time.The parser can do two possible things.If the input symbol is.I ELSE ,it is possible to shift into state45.State 45 will have, as part of its description, the line.DSstat : IF ( cond ) stat ELSE\_stat.DEsince the.I ELSEwill have been shifted in this state.Back in state 23, the alternative action, described by ``\fB.\fR'',is to be done if the input symbol is not mentioned explicitly in the above actions; thus,in this case, if the input symbol is not.I ELSE ,the parser reduces by grammar rule 18:.DSstat : IF \'(\' cond \')\' stat.DEOnce again, notice that the numbers following ``shift'' commands refer to other states,while the numbers following ``reduce'' commands refer to grammarrule numbers.In the.I y.outputfile, the rule numbers are printed after those rules which can be reduced.In most one states, there will be at most reduce action possible in thestate, and this will be the default command.The user who encounters unexpected shift/reduce conflicts will probably want tolook at the verbose output to decide whether the default actions are appropriate.In really tough cases, the user might need to know more aboutthe behavior and construction of the parser than can be covered here.In this case, one of the theoretical references.[Aho Johnson Surveys Parsing.].[Aho Johnson Ullman Deterministic Ambiguous.].[Aho Ullman Principles Design.]might be consulted; the services of a local guru might also be appropriate.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -