tests predicate rendering in alternatives, in non-trivial cardinalities,
and setup block rendering. in both the production grammar and content
assist grammar.
added debug grammar generators for production grammar and content assist
grammar which use DebugGrammarNaming to avoid null-ptr because of
missing adapters in ecore objects. (existing AntlrDebugGrammarGenerator
can't be used because setup blocks are handled by AntlrGrammarGenerator
and AntlrContentAssistGrammarGenerator respectively, not
AbstractAntlrGrammarGenerator.)
fixed small details in rendered output (removed guard of rule comment
and trimmed setup block).
- added test case of recursive rules (with start rule) and optional
context
- disable cardinalities (and repetitions in unordered groups) in context
analysis if the current element was already seen and there was no
progress this recursion - the element itself will not be returned by
getNextElementsInContext()
- changed isStartRule() and findAllRuleCalls() in GrammarUtils to only
compare the name of the rule. otherwise constructed paths cause problems
(since the rule object is not the same and the alternatives-attribute
might (very probably) not be equal in the constructed rule object).
- changed findGuardForOptionalCardinalityWithoutContext() in
HoistingProcessor to avoid the construction of virtual elements and
instead provide the virtual cardinality to the token analysis via a new
parameter.
- fixed testCardinalityQuestionmarkWithExternalContext_expectContextCheck()
test case (context analysis is not possible if the context equals the
remainder of the prefixed alternative; changed context to be different)
empty paths are keep the state of the prefix including the empty flag
which causes empty paths in alternatives to be lost.
fix: create new token state with prefix (reset empty flag)
recursive (only tail recursion) causes problems because context of rule
call causes endless recursion in getNextElementsInContext()
example:
S: {S} $$ p0 $$?=> 's'
| $$ p1 $$?=> 's' s=S
;
solution: added set of visited rule calls to parameter list, skip rule
call if it was already handled by another recursion
added test cases
when context analysis is needed and an element in context has multiple
cardinality and contains empty paths (e.g. ?-quantified) the quantified
element will be recursed endlessly without the token analysis path even
being done (since there is always an empty path) - this also applies to
unordered groups.
recognizing empty paths is not trivial because of recursive rules.
solution: save "call stack" (actually just a set of visited elements)
during recursions in context analysis. if an element is seen multiple
times we check if there is any progress in the analysis paths. if not
this is an endless recursion
-> throw exception
non-trivial quantifiers in context path are not handled correctly.
change to getNextElementsInContext():
add non-trivially quantified elements in path (except first element
because of potential endless recursion) to result set
when the following context element is optional, the minimal sequence is
not going to get bigger. in this case further context analysis is
blocked by the exception.
=> removed exception
also made sure getNextElementsInContext() won't return non-token,
non-compound elements like actions or predicates.
is necessary because otherwise the identity analysis might not be able
to detect if paths are identical up to the token limit (which should
cause an error)
testRecursiveRuleCallingAlternative_expectCorrectGuard
guard for nested alternatives might not be optimal if the positions that
discriminate in the first alternatives is different from the positions
needed on the next one
collapsed paths loose the containing token guard
=> fixed problem
+ added positional condition in token sequence guard constructor to not
check positions twice (order matters: give local token guard first in
case it is sufficient)
removed testNestedAlternativesWithSingleTokenDifference, because it is
wrong: 'a' 'b' 'd' with p1 satisfies semantic predicates but not the
generated guard condition
nested prefix alternatives analysis
now flattenPaths() considers following repetitions
new problem: unordered groups and non-trivial cardinalities without
non-optional elements causes explosion of generated alternatives, which
in turn cause the identity analysis to go out of control
example: S: ('a'? | 'b'?)+
with a token limit of 10 the nested prefix alternatives analysis would
generate over 1300 alternatives
current quick fix: limit of alternatives
after minimal path difference analysis failed, flatten paths (limited by
token limit; justification: identity check would error out if paths are
not distinguishable within the limit) and recompute alternative guard.
now nested prefixes will be collapsed with all corresponding guard
conditions
cardinality * is only possible if all element in the unordered group are
optional. This case doesn't matter for hoisting or rather is already
dealt with in the containing group (the guard of the resulting
alternatives won't have a terminal).