diff options
Diffstat (limited to 'subprojects/language/src/main/java/tools/refinery/language/parser/antlr')
2 files changed, 34 insertions, 29 deletions
diff --git a/subprojects/language/src/main/java/tools/refinery/language/parser/antlr/IdentifierTokenProvider.java b/subprojects/language/src/main/java/tools/refinery/language/parser/antlr/IdentifierTokenProvider.java index 306a86fc..0e19357f 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/parser/antlr/IdentifierTokenProvider.java +++ b/subprojects/language/src/main/java/tools/refinery/language/parser/antlr/IdentifierTokenProvider.java | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | 2 | * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors <https://refinery.tools/> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
@@ -59,7 +59,7 @@ public class IdentifierTokenProvider { | |||
59 | 59 | ||
60 | private void createValueToTokenIdMap() { | 60 | private void createValueToTokenIdMap() { |
61 | var tokenIdToValueMap = tokenDefProvider.getTokenDefMap(); | 61 | var tokenIdToValueMap = tokenDefProvider.getTokenDefMap(); |
62 | valueToTokenIdMap = new HashMap<>(tokenIdToValueMap.size()); | 62 | valueToTokenIdMap = HashMap.newHashMap(tokenIdToValueMap.size()); |
63 | for (var entry : tokenIdToValueMap.entrySet()) { | 63 | for (var entry : tokenIdToValueMap.entrySet()) { |
64 | valueToTokenIdMap.put(entry.getValue(), entry.getKey()); | 64 | valueToTokenIdMap.put(entry.getValue(), entry.getKey()); |
65 | } | 65 | } |
@@ -74,17 +74,16 @@ public class IdentifierTokenProvider { | |||
74 | } | 74 | } |
75 | 75 | ||
76 | private void collectIdentifierTokensFromElement(AbstractElement element) { | 76 | private void collectIdentifierTokensFromElement(AbstractElement element) { |
77 | if (element instanceof Alternatives alternatives) { | 77 | switch (element) { |
78 | for (var alternative : alternatives.getElements()) { | 78 | case Alternatives alternatives -> { |
79 | collectIdentifierTokensFromElement(alternative); | 79 | for (var alternative : alternatives.getElements()) { |
80 | } | 80 | collectIdentifierTokensFromElement(alternative); |
81 | } else if (element instanceof RuleCall ruleCall) { | 81 | } |
82 | collectIdentifierTokensFromRule(ruleCall.getRule()); | 82 | } |
83 | } else if (element instanceof Keyword keyword) { | 83 | case RuleCall ruleCall -> collectIdentifierTokensFromRule(ruleCall.getRule()); |
84 | collectToken("'" + keyword.getValue() + "'"); | 84 | case Keyword keyword -> collectToken("'" + keyword.getValue() + "'"); |
85 | } else { | 85 | default -> throw new IllegalArgumentException("Unknown Xtext grammar element: " + element); |
86 | throw new IllegalArgumentException("Unknown Xtext grammar element: " + element); | 86 | } |
87 | } | ||
88 | } | 87 | } |
89 | 88 | ||
90 | private void collectToken(String value) { | 89 | private void collectToken(String value) { |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/parser/antlr/ProblemTokenSource.java b/subprojects/language/src/main/java/tools/refinery/language/parser/antlr/ProblemTokenSource.java index 5b91a6cc..487e4ceb 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/parser/antlr/ProblemTokenSource.java +++ b/subprojects/language/src/main/java/tools/refinery/language/parser/antlr/ProblemTokenSource.java | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | 2 | * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors <https://refinery.tools/> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
@@ -28,6 +28,8 @@ public class ProblemTokenSource implements TokenSource { | |||
28 | 28 | ||
29 | private boolean seenId; | 29 | private boolean seenId; |
30 | 30 | ||
31 | private boolean lastVisible; | ||
32 | |||
31 | public ProblemTokenSource(TokenSource delegate) { | 33 | public ProblemTokenSource(TokenSource delegate) { |
32 | this.delegate = delegate; | 34 | this.delegate = delegate; |
33 | } | 35 | } |
@@ -47,18 +49,18 @@ public class ProblemTokenSource implements TokenSource { | |||
47 | 49 | ||
48 | @Override | 50 | @Override |
49 | public Token nextToken() { | 51 | public Token nextToken() { |
50 | if (!buffer.isEmpty()) { | 52 | boolean fromStream = buffer.isEmpty(); |
51 | return buffer.removeFirst(); | 53 | var token = fromStream ? delegate.nextToken() : buffer.removeFirst(); |
52 | } | 54 | if (seenId) { |
53 | var token = delegate.nextToken(); | 55 | if (fromStream && isPlusOrTransitiveClosure(token) && peekForTransitiveClosure()) { |
54 | if (isIdentifier(token)) { | ||
55 | seenId = true; | ||
56 | } else if (seenId && isPlusOrTransitiveClosure(token)) { | ||
57 | if (peekForTransitiveClosure()) { | ||
58 | token.setType(InternalProblemParser.RULE_TRANSITIVE_CLOSURE); | 56 | token.setType(InternalProblemParser.RULE_TRANSITIVE_CLOSURE); |
57 | } else if (lastVisible && isQualifiedNameSeparator(token)) { | ||
58 | token.setType(InternalProblemParser.RULE_QUALIFIED_NAME_SEPARATOR); | ||
59 | } | 59 | } |
60 | } else if (isVisibleToken(token)) { | 60 | } |
61 | seenId = false; | 61 | lastVisible = isVisibleToken(token); |
62 | if (lastVisible) { | ||
63 | seenId = isIdentifier(token); | ||
62 | } | 64 | } |
63 | return token; | 65 | return token; |
64 | } | 66 | } |
@@ -76,6 +78,10 @@ public class ProblemTokenSource implements TokenSource { | |||
76 | return token.getType() == InternalProblemParser.PlusSign; | 78 | return token.getType() == InternalProblemParser.PlusSign; |
77 | } | 79 | } |
78 | 80 | ||
81 | protected boolean isQualifiedNameSeparator(Token token) { | ||
82 | return token.getType() == InternalProblemParser.ColonColon; | ||
83 | } | ||
84 | |||
79 | protected boolean isVisibleToken(Token token) { | 85 | protected boolean isVisibleToken(Token token) { |
80 | int tokenId = token.getType(); | 86 | int tokenId = token.getType(); |
81 | return tokenId != InternalProblemParser.RULE_WS && tokenId != InternalProblemParser.RULE_SL_COMMENT && | 87 | return tokenId != InternalProblemParser.RULE_WS && tokenId != InternalProblemParser.RULE_SL_COMMENT && |
@@ -87,11 +93,16 @@ public class ProblemTokenSource implements TokenSource { | |||
87 | if (token.getType() != InternalProblemParser.LeftParenthesis) { | 93 | if (token.getType() != InternalProblemParser.LeftParenthesis) { |
88 | return false; | 94 | return false; |
89 | } | 95 | } |
96 | boolean allowFullyQualifiedName = true; | ||
90 | while (true) { | 97 | while (true) { |
91 | token = peekWithSkipWhitespace(); | 98 | token = peekWithSkipWhitespace(); |
99 | if (allowFullyQualifiedName && token.getType() == InternalProblemParser.ColonColon) { | ||
100 | token = peekWithSkipWhitespace(); | ||
101 | } | ||
92 | if (!isIdentifier(token)) { | 102 | if (!isIdentifier(token)) { |
93 | return false; | 103 | return false; |
94 | } | 104 | } |
105 | allowFullyQualifiedName = false; | ||
95 | token = peekWithSkipWhitespace(); | 106 | token = peekWithSkipWhitespace(); |
96 | switch (token.getType()) { | 107 | switch (token.getType()) { |
97 | case InternalProblemParser.Comma: | 108 | case InternalProblemParser.Comma: |
@@ -112,11 +123,6 @@ public class ProblemTokenSource implements TokenSource { | |||
112 | 123 | ||
113 | protected Token peekToken() { | 124 | protected Token peekToken() { |
114 | var token = delegate.nextToken(); | 125 | var token = delegate.nextToken(); |
115 | if (isIdentifier(token)) { | ||
116 | seenId = true; | ||
117 | } else if (isVisibleToken(token)) { | ||
118 | seenId = false; | ||
119 | } | ||
120 | buffer.addLast(token); | 126 | buffer.addLast(token); |
121 | return token; | 127 | return token; |
122 | } | 128 | } |