Skip to content

Commit

Permalink
generator: include first-check for rules with non-external predicates
Browse files Browse the repository at this point in the history
  • Loading branch information
gregsh committed May 18, 2018
1 parent a2227fd commit 51f18c8
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 8 deletions.
17 changes: 11 additions & 6 deletions src/org/intellij/grammar/analysis/BnfFirstNextAnalyzer.java
Expand Up @@ -304,7 +304,7 @@ else if (expression instanceof BnfPredicate) {
Set<BnfExpression> conditions = calcFirstInner(predicateExpression, newExprSet(), visited, null);
Set<BnfExpression> next;
List<BnfExpression> externalCond = Collections.emptyList();
List<BnfExpression> externalNext;
List<BnfExpression> externalNext = Collections.emptyList();
if (!visited.add(predicateExpression)) {
skip = true;
next = Collections.emptySet();
Expand All @@ -320,7 +320,7 @@ else if (expression instanceof BnfPredicate) {
visited.remove(predicateExpression);
externalCond = filterExternalMethods(conditions);
externalNext = filterExternalMethods(next);
if (!skip) skip = !externalNext.isEmpty() || !externalCond.isEmpty();
if (!skip) skip = !externalCond.isEmpty();
}
Set<BnfExpression> mixed = newExprSet();
if (elementType == BnfTypes.BNF_OP_AND) {
Expand All @@ -337,10 +337,15 @@ else if (!conditions.contains(BNF_MATCHES_EOF)) {
mixed.addAll(conditions);
}
else {
mixed.addAll(next);
mixed.retainAll(conditions);
if (mixed.isEmpty() && !involvesTextMatching(conditions)) {
mixed.add(BNF_MATCHES_NOTHING);
if (externalNext.isEmpty()) {
mixed.addAll(next);
mixed.retainAll(conditions);
if (mixed.isEmpty() && !involvesTextMatching(conditions)) {
mixed.add(BNF_MATCHES_NOTHING);
}
}
else {
mixed.addAll(conditions);
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions tests/org/intellij/grammar/BnfFirstNextTest.java
Expand Up @@ -42,8 +42,9 @@ protected void setUp() throws Exception {
public void testAndOrNot2() { doFirstTest("r ::= Y? (!X | &X) X", "X", "Y"); }
public void testNotOrNot3() { doFirstTest("r ::= Y? (!X | !X) X", MATCHES_NOTHING, "Y"); }
public void testNotText() { doFirstTest("r ::= !'a' s external s ::= parseA", "#parseA"); }
public void testAndText() { doFirstTest("r ::= &'a' s external s ::= parseA", "#parseA"); }
public void testAndExternal() { doFirstTest("r ::= &A s external s ::= parseA", "#parseA"); }
public void testAndText() { doFirstTest("r ::= &'a' s external s ::= parseA", "'a'"); }
public void testAndExternal() { doFirstTest("r ::= &A s external s ::= parseA", "A"); }
public void testAndExternalPredicate() { doFirstTest("r ::= &p s external s ::= parseA external p ::= parseB", "#parseA", "#parseB"); }
public void testNotSeqTrivial() { doFirstTest("r ::= !(X) (X Z)", MATCHES_NOTHING); }
public void testNotSeq() { doFirstTest("r ::= !(X Y) (X Z)", "X"); }
public void testAndSeq() { doFirstTest("r ::= (&(X | Y) | !X) X", "X"); }
Expand Down

0 comments on commit 51f18c8

Please sign in to comment.