Managing conflicts
When new grammar is written from scratch it usually reports many conflicts. Resolving them may take a lot of time and effort. Grammar author in his quest for working parser may choose to forcibly disable conflicts using all possible means. Once preliminary version of parser is ready, it may be necessary to make another iteration, review conflicts and correct them where necessary.
To effectively manage grammar conflicts it is necessary to be able to:
- disable and enable conflicts, both globally or selectively
- inspect all conflicts including resolved, active, enabled or disabled
- identify the cause of each conflict
- check which mechanism was used to resolve each conflicts
Conflict statuses
A single conflict can be in either of following states:
- resolved – conflict was successfully resolved using one of available mechanisms or settings. No warning message is reported for it.
It must be remembered that the original cause of conflict remains in grammar. It is even possible that conflict was resolved incorrectly and grammar does not work as it should. - resolved with warning – conflict was resolved, but the mechanism used to resolve the conflict is configured to still generate a warning. This is usually a consequence of setting one of global conflict resolving options (like Parser.Conflicts.SR_ResolveAsShift) to YesWarn.
- conflict – conflict was not resolved. Parser cannot be generated.
- disabled – conflict does not have to be resolved since other decisions (taken for other conflicts) made this conflict irrelevant.
Disabling conflict warnings
Warnings reported for conflicts can be disabled on per-production level. Only shift-reduce conflicts can be handled this way.
Disabling conflict warnings can be used only with conflicts that are resolved, but still generate a warning. Conflicts that are not resolved and generate an error cannot be disabled.
The %igsr option set for particular production disables shift-reduce conflicts when this production is candidate for reduction. This option has several configurations:
%igsr
disables all s-r conflicts for production (being candidate for reduction). Single occurrence allowed.
%igsr terminal
disables all s-r conflicts for production (which would be reduced) against given terminal (which would be shifted). Multiple occurrences for single production allowed.
%igsr ^place
disables all s-r conflicts for production against given place. The place must mark a point inside other production which precedes the shifted token with which conflict occurs. Multiple occurrences allowed. Referenced place may include several points in different rules. In such case s-r conflicts with all these places are disabled.
%igsr count
disables a given number (count) of conflicts for the production regardless of their character. This option can be used on top of preceding %isgr options to silence any remaining warnings.
Examples
ENT: A B ^myPlace C; // production 1
ENT: A B %igsr ^myPlace; // ignore conflict with token C at ^myPlace in production 1
ENT2: A B C %igsr "+" %igsr D %igsr 5; // ignore conflict with "+", with 'D', and five more conflicts
Inspecting conflicts
Full list of grammar conflicts is included in Alpag report, which can be generated using –pr switch. All conflicts are shown in the report twice:
- for each automaton state
- in dedicated section listing all conflicts.
A state containing conflicts is reported as follows:
states
...
state #101
itemset
...
actions
...
conflicts
error
s-r under ELSE shift to #10 or reduce by @3 to IF_INSTR conflict
...
warn
...
resolved
s-r under IDENT shift to #56 or reduce by @169 to NONTERM resolved
as shift using shiftOverReduce
disabled
...
Conflicts are reported in separate groups for active conflicts (error), conflicts resolved with warning (warn), conflicts resolved successfully (resolved) and disabled ones.
The summary section with conflicts appears at the end of file and looks like this:
conflicts
totalCount: 259
conflictCount: 5
warnResCount: 0
resCount: 265
s-r under ELSE shift to #10 or reduce by @3 to IF_INSTR conflict
s-r under IDENT shift to #56 or reduce by @169 to NONTERM resolved as
shift using shiftOverReduce
...
Format of conflict description is the same in either case:
conflictType under TERMINAL alternative1 or alternative2 status [as decision using method [warn ignored by ignoreWay]]
where:
- conflictType - s-r or r-r for shift-reduce or reduce-reduce conflicts
- TERMINAL - input terminal symbol for which conflict was generated
- alternative1, alternative2 - alternative ways of resolving the conflict. The syntax is:
shift to #stateId – for shift, and
reduce by @prodId to NONTERM – for reduction - status - status of the conflict, possible values are: conflict, disabled, resolved, resolved_warn
If conflict is resolved (with warning or not) the decision is given after 'as':
- decision - possible values are: shift, reduce
- method - method used to resolve the conflict. Possible value are: precedence, assoc, noassoc, shiftOverReduce, ruleOrder, prefereLahs
If warning was explicitly disabled in grammar (ignored) then additional element appears:
ignoreWay - describes method used to disable the warning. Possible values are: place, token, count, all. These values correspond to different configurations of %igsr option attached to production.