Skip to content

Commit c2c9758

Browse files
committed
Disambiguate grammar
Introduced more elaborate recursive descent parsing.
1 parent 29f50fe commit c2c9758

8 files changed

Lines changed: 2476 additions & 1454 deletions

File tree

poetry.lock

Lines changed: 202 additions & 201 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/xplore_path/XplorePathGrammar.g4

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -146,31 +146,58 @@ xplorePath
146146
//
147147
// In INTERPRETATION 1, "coerceFallbck" is consumed by the inner expr. In INTERPRETATION 2, it's consumed by the
148148
// outer expr.
149-
expr
150-
: (KW_ANY | KW_ALL) expr coerceFallback? # ExprBoolAggregate
151-
| expr joinOp expr joinCond # ExprJoin
152-
| expr (KW_INTERSECT | KW_EXCEPT) expr # ExprSetIntersect
153-
| expr (KW_UNION | P) expr # ExprSetUnion
154-
| KW_LABEL expr # ExprExtractLabel
155-
| KW_POSITION expr # ExprExtractPosition
156-
| KW_NOT expr coerceFallback? # ExprNot
157-
| expr orOp expr coerceFallback? # ExprOr
158-
| expr andOp expr coerceFallback? # ExprAnd
159-
| expr relOp expr coerceFallback? # ExprComparison
160-
| expr addOp expr coerceFallback? # ExprAdditive
161-
| expr mulOp expr coerceFallback? # ExprMultiplicative
162-
| negateOrPathOrAtomic # ExprAtomicOrPathOrEncapsulate
163-
;
164-
165-
// Why isn't negateOrPathOrAtomic directly tied embedded within expr? It was, and the ExprUnary alternative was defined
166-
// as "(MINUS | PLUS) expr". This worked fine except that when you did something like -1-1, it evaluated as -(1-1)
167-
// instead of (-1)-1. The later evaluation is the correct evaluation order, and that's what happens now with this
168-
// current grammar.
169-
negateOrPathOrAtomic
170-
: (MINUS | PLUS) negateOrPathOrAtomic coerceFallback? # ExprUnary
171-
| path # ExprPath // REMINDER: Don't do "path filter? ..." - it'll cause ambiguity because each path element ends with "filter?" - so if there's a filter after the last element, it doesn't know which rule it should apply to (the element's filter or this rule's filter)
172-
| path argumentList filter? # ExprPathInvoke // REMINDER: Don't do "path filter? ..." - it'll cause ambiguity because each path element ends with "filter?" - so if there's a filter after the last element, it doesn't know which rule it should apply to (the element's filter or this rule's filter)
173-
| atomic # ExprAtomic
149+
expr: exprBoolAggregate;
150+
151+
exprBoolAggregate
152+
: (KW_ANY | KW_ALL) exprJoin coerceFallback? # ExprBoolAggregateHit
153+
| exprJoin # ExprBoolAggregateForward
154+
;
155+
exprJoin
156+
: exprJoin joinOp exprSetIntersect joinCond # ExprJoinHit
157+
| exprSetIntersect # ExprJoinForward
158+
;
159+
exprSetIntersect
160+
: exprSetIntersect (KW_INTERSECT | KW_EXCEPT) exprSetUnion # ExprSetIntersectHit
161+
| exprSetUnion # ExprSetIntersectForward
162+
;
163+
exprSetUnion
164+
: exprSetUnion (KW_UNION | P) exprOr # ExprSetUnionHit
165+
| exprOr # ExprSetUnionForward
166+
;
167+
exprOr
168+
: exprOr orOp exprAnd coerceFallback? # ExprOrHit
169+
| exprAnd # ExprOrForward
170+
;
171+
exprAnd
172+
: exprAnd andOp exprNot coerceFallback? # ExprAndHit
173+
| exprNot # ExprAndForward
174+
;
175+
exprNot
176+
: KW_NOT exprComparison coerceFallback? # ExprNotHit
177+
| exprComparison # ExprNotForward
178+
;
179+
exprComparison
180+
: exprComparison relOp exprAdditive coerceFallback? # ExprComparisonHit
181+
| exprAdditive # ExprComparisonForward
182+
;
183+
exprAdditive
184+
: exprAdditive addOp exprMultiplicative coerceFallback? # ExprAdditiveHit
185+
| exprMultiplicative # ExprAdditiveForward
186+
;
187+
exprMultiplicative
188+
: exprMultiplicative mulOp exprUnary coerceFallback? # ExprMultiplicativeHit
189+
| exprUnary # ExprMultiplicativeForward
190+
;
191+
exprUnary
192+
: (MINUS | PLUS) exprPathOrAtomic coerceFallback? # ExprUnaryNegateHit
193+
| KW_LABEL exprPathOrAtomic # ExprUnaryLabelHit
194+
| KW_POSITION exprPathOrAtomic # ExprUnaryPositionHit
195+
| exprPathOrAtomic # ExprUnaryForward
196+
;
197+
exprPathOrAtomic
198+
: path # ExprPath // REMINDER: Don't do "path filter? ..." - it'll cause ambiguity because each path element ends with "filter?" - so if there's a filter after the last element, it doesn't know which rule it should apply to (the element's filter or this rule's filter)
199+
| path argumentList filter? # ExprPathInvoke // REMINDER: Don't do "path filter? ..." - it'll cause ambiguity because each path element ends with "filter?" - so if there's a filter after the last element, it doesn't know which rule it should apply to (the element's filter or this rule's filter)
200+
| atomic # ExprAtomic
174201
;
175202

176203
atomic

src/xplore_path/XplorePathGrammar.interp

Lines changed: 13 additions & 2 deletions
Large diffs are not rendered by default.

src/xplore_path/XplorePathGrammarListener.py

Lines changed: 155 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -17,129 +17,228 @@ def exitXplorePath(self, ctx:XplorePathGrammarParser.XplorePathContext):
1717
pass
1818

1919

20-
# Enter a parse tree produced by XplorePathGrammarParser#ExprBoolAggregate.
21-
def enterExprBoolAggregate(self, ctx:XplorePathGrammarParser.ExprBoolAggregateContext):
20+
# Enter a parse tree produced by XplorePathGrammarParser#expr.
21+
def enterExpr(self, ctx:XplorePathGrammarParser.ExprContext):
2222
pass
2323

24-
# Exit a parse tree produced by XplorePathGrammarParser#ExprBoolAggregate.
25-
def exitExprBoolAggregate(self, ctx:XplorePathGrammarParser.ExprBoolAggregateContext):
24+
# Exit a parse tree produced by XplorePathGrammarParser#expr.
25+
def exitExpr(self, ctx:XplorePathGrammarParser.ExprContext):
2626
pass
2727

2828

29-
# Enter a parse tree produced by XplorePathGrammarParser#ExprSetIntersect.
30-
def enterExprSetIntersect(self, ctx:XplorePathGrammarParser.ExprSetIntersectContext):
29+
# Enter a parse tree produced by XplorePathGrammarParser#ExprBoolAggregateHit.
30+
def enterExprBoolAggregateHit(self, ctx:XplorePathGrammarParser.ExprBoolAggregateHitContext):
3131
pass
3232

33-
# Exit a parse tree produced by XplorePathGrammarParser#ExprSetIntersect.
34-
def exitExprSetIntersect(self, ctx:XplorePathGrammarParser.ExprSetIntersectContext):
33+
# Exit a parse tree produced by XplorePathGrammarParser#ExprBoolAggregateHit.
34+
def exitExprBoolAggregateHit(self, ctx:XplorePathGrammarParser.ExprBoolAggregateHitContext):
3535
pass
3636

3737

38-
# Enter a parse tree produced by XplorePathGrammarParser#ExprComparison.
39-
def enterExprComparison(self, ctx:XplorePathGrammarParser.ExprComparisonContext):
38+
# Enter a parse tree produced by XplorePathGrammarParser#ExprBoolAggregateForward.
39+
def enterExprBoolAggregateForward(self, ctx:XplorePathGrammarParser.ExprBoolAggregateForwardContext):
4040
pass
4141

42-
# Exit a parse tree produced by XplorePathGrammarParser#ExprComparison.
43-
def exitExprComparison(self, ctx:XplorePathGrammarParser.ExprComparisonContext):
42+
# Exit a parse tree produced by XplorePathGrammarParser#ExprBoolAggregateForward.
43+
def exitExprBoolAggregateForward(self, ctx:XplorePathGrammarParser.ExprBoolAggregateForwardContext):
4444
pass
4545

4646

47-
# Enter a parse tree produced by XplorePathGrammarParser#ExprExtractLabel.
48-
def enterExprExtractLabel(self, ctx:XplorePathGrammarParser.ExprExtractLabelContext):
47+
# Enter a parse tree produced by XplorePathGrammarParser#ExprJoinForward.
48+
def enterExprJoinForward(self, ctx:XplorePathGrammarParser.ExprJoinForwardContext):
4949
pass
5050

51-
# Exit a parse tree produced by XplorePathGrammarParser#ExprExtractLabel.
52-
def exitExprExtractLabel(self, ctx:XplorePathGrammarParser.ExprExtractLabelContext):
51+
# Exit a parse tree produced by XplorePathGrammarParser#ExprJoinForward.
52+
def exitExprJoinForward(self, ctx:XplorePathGrammarParser.ExprJoinForwardContext):
5353
pass
5454

5555

56-
# Enter a parse tree produced by XplorePathGrammarParser#ExprNot.
57-
def enterExprNot(self, ctx:XplorePathGrammarParser.ExprNotContext):
56+
# Enter a parse tree produced by XplorePathGrammarParser#ExprJoinHit.
57+
def enterExprJoinHit(self, ctx:XplorePathGrammarParser.ExprJoinHitContext):
5858
pass
5959

60-
# Exit a parse tree produced by XplorePathGrammarParser#ExprNot.
61-
def exitExprNot(self, ctx:XplorePathGrammarParser.ExprNotContext):
60+
# Exit a parse tree produced by XplorePathGrammarParser#ExprJoinHit.
61+
def exitExprJoinHit(self, ctx:XplorePathGrammarParser.ExprJoinHitContext):
6262
pass
6363

6464

65-
# Enter a parse tree produced by XplorePathGrammarParser#ExprAtomicOrPathOrEncapsulate.
66-
def enterExprAtomicOrPathOrEncapsulate(self, ctx:XplorePathGrammarParser.ExprAtomicOrPathOrEncapsulateContext):
65+
# Enter a parse tree produced by XplorePathGrammarParser#ExprSetIntersectHit.
66+
def enterExprSetIntersectHit(self, ctx:XplorePathGrammarParser.ExprSetIntersectHitContext):
6767
pass
6868

69-
# Exit a parse tree produced by XplorePathGrammarParser#ExprAtomicOrPathOrEncapsulate.
70-
def exitExprAtomicOrPathOrEncapsulate(self, ctx:XplorePathGrammarParser.ExprAtomicOrPathOrEncapsulateContext):
69+
# Exit a parse tree produced by XplorePathGrammarParser#ExprSetIntersectHit.
70+
def exitExprSetIntersectHit(self, ctx:XplorePathGrammarParser.ExprSetIntersectHitContext):
7171
pass
7272

7373

74-
# Enter a parse tree produced by XplorePathGrammarParser#ExprAdditive.
75-
def enterExprAdditive(self, ctx:XplorePathGrammarParser.ExprAdditiveContext):
74+
# Enter a parse tree produced by XplorePathGrammarParser#ExprSetIntersectForward.
75+
def enterExprSetIntersectForward(self, ctx:XplorePathGrammarParser.ExprSetIntersectForwardContext):
7676
pass
7777

78-
# Exit a parse tree produced by XplorePathGrammarParser#ExprAdditive.
79-
def exitExprAdditive(self, ctx:XplorePathGrammarParser.ExprAdditiveContext):
78+
# Exit a parse tree produced by XplorePathGrammarParser#ExprSetIntersectForward.
79+
def exitExprSetIntersectForward(self, ctx:XplorePathGrammarParser.ExprSetIntersectForwardContext):
8080
pass
8181

8282

83-
# Enter a parse tree produced by XplorePathGrammarParser#ExprAnd.
84-
def enterExprAnd(self, ctx:XplorePathGrammarParser.ExprAndContext):
83+
# Enter a parse tree produced by XplorePathGrammarParser#ExprSetUnionForward.
84+
def enterExprSetUnionForward(self, ctx:XplorePathGrammarParser.ExprSetUnionForwardContext):
8585
pass
8686

87-
# Exit a parse tree produced by XplorePathGrammarParser#ExprAnd.
88-
def exitExprAnd(self, ctx:XplorePathGrammarParser.ExprAndContext):
87+
# Exit a parse tree produced by XplorePathGrammarParser#ExprSetUnionForward.
88+
def exitExprSetUnionForward(self, ctx:XplorePathGrammarParser.ExprSetUnionForwardContext):
8989
pass
9090

9191

92-
# Enter a parse tree produced by XplorePathGrammarParser#ExprExtractPosition.
93-
def enterExprExtractPosition(self, ctx:XplorePathGrammarParser.ExprExtractPositionContext):
92+
# Enter a parse tree produced by XplorePathGrammarParser#ExprSetUnionHit.
93+
def enterExprSetUnionHit(self, ctx:XplorePathGrammarParser.ExprSetUnionHitContext):
9494
pass
9595

96-
# Exit a parse tree produced by XplorePathGrammarParser#ExprExtractPosition.
97-
def exitExprExtractPosition(self, ctx:XplorePathGrammarParser.ExprExtractPositionContext):
96+
# Exit a parse tree produced by XplorePathGrammarParser#ExprSetUnionHit.
97+
def exitExprSetUnionHit(self, ctx:XplorePathGrammarParser.ExprSetUnionHitContext):
9898
pass
9999

100100

101-
# Enter a parse tree produced by XplorePathGrammarParser#ExprOr.
102-
def enterExprOr(self, ctx:XplorePathGrammarParser.ExprOrContext):
101+
# Enter a parse tree produced by XplorePathGrammarParser#ExprOrForward.
102+
def enterExprOrForward(self, ctx:XplorePathGrammarParser.ExprOrForwardContext):
103103
pass
104104

105-
# Exit a parse tree produced by XplorePathGrammarParser#ExprOr.
106-
def exitExprOr(self, ctx:XplorePathGrammarParser.ExprOrContext):
105+
# Exit a parse tree produced by XplorePathGrammarParser#ExprOrForward.
106+
def exitExprOrForward(self, ctx:XplorePathGrammarParser.ExprOrForwardContext):
107107
pass
108108

109109

110-
# Enter a parse tree produced by XplorePathGrammarParser#ExprMultiplicative.
111-
def enterExprMultiplicative(self, ctx:XplorePathGrammarParser.ExprMultiplicativeContext):
110+
# Enter a parse tree produced by XplorePathGrammarParser#ExprOrHit.
111+
def enterExprOrHit(self, ctx:XplorePathGrammarParser.ExprOrHitContext):
112112
pass
113113

114-
# Exit a parse tree produced by XplorePathGrammarParser#ExprMultiplicative.
115-
def exitExprMultiplicative(self, ctx:XplorePathGrammarParser.ExprMultiplicativeContext):
114+
# Exit a parse tree produced by XplorePathGrammarParser#ExprOrHit.
115+
def exitExprOrHit(self, ctx:XplorePathGrammarParser.ExprOrHitContext):
116116
pass
117117

118118

119-
# Enter a parse tree produced by XplorePathGrammarParser#ExprSetUnion.
120-
def enterExprSetUnion(self, ctx:XplorePathGrammarParser.ExprSetUnionContext):
119+
# Enter a parse tree produced by XplorePathGrammarParser#ExprAndHit.
120+
def enterExprAndHit(self, ctx:XplorePathGrammarParser.ExprAndHitContext):
121121
pass
122122

123-
# Exit a parse tree produced by XplorePathGrammarParser#ExprSetUnion.
124-
def exitExprSetUnion(self, ctx:XplorePathGrammarParser.ExprSetUnionContext):
123+
# Exit a parse tree produced by XplorePathGrammarParser#ExprAndHit.
124+
def exitExprAndHit(self, ctx:XplorePathGrammarParser.ExprAndHitContext):
125125
pass
126126

127127

128-
# Enter a parse tree produced by XplorePathGrammarParser#ExprJoin.
129-
def enterExprJoin(self, ctx:XplorePathGrammarParser.ExprJoinContext):
128+
# Enter a parse tree produced by XplorePathGrammarParser#ExprAndForward.
129+
def enterExprAndForward(self, ctx:XplorePathGrammarParser.ExprAndForwardContext):
130130
pass
131131

132-
# Exit a parse tree produced by XplorePathGrammarParser#ExprJoin.
133-
def exitExprJoin(self, ctx:XplorePathGrammarParser.ExprJoinContext):
132+
# Exit a parse tree produced by XplorePathGrammarParser#ExprAndForward.
133+
def exitExprAndForward(self, ctx:XplorePathGrammarParser.ExprAndForwardContext):
134134
pass
135135

136136

137-
# Enter a parse tree produced by XplorePathGrammarParser#ExprUnary.
138-
def enterExprUnary(self, ctx:XplorePathGrammarParser.ExprUnaryContext):
137+
# Enter a parse tree produced by XplorePathGrammarParser#ExprNotHit.
138+
def enterExprNotHit(self, ctx:XplorePathGrammarParser.ExprNotHitContext):
139139
pass
140140

141-
# Exit a parse tree produced by XplorePathGrammarParser#ExprUnary.
142-
def exitExprUnary(self, ctx:XplorePathGrammarParser.ExprUnaryContext):
141+
# Exit a parse tree produced by XplorePathGrammarParser#ExprNotHit.
142+
def exitExprNotHit(self, ctx:XplorePathGrammarParser.ExprNotHitContext):
143+
pass
144+
145+
146+
# Enter a parse tree produced by XplorePathGrammarParser#ExprNotForward.
147+
def enterExprNotForward(self, ctx:XplorePathGrammarParser.ExprNotForwardContext):
148+
pass
149+
150+
# Exit a parse tree produced by XplorePathGrammarParser#ExprNotForward.
151+
def exitExprNotForward(self, ctx:XplorePathGrammarParser.ExprNotForwardContext):
152+
pass
153+
154+
155+
# Enter a parse tree produced by XplorePathGrammarParser#ExprComparisonForward.
156+
def enterExprComparisonForward(self, ctx:XplorePathGrammarParser.ExprComparisonForwardContext):
157+
pass
158+
159+
# Exit a parse tree produced by XplorePathGrammarParser#ExprComparisonForward.
160+
def exitExprComparisonForward(self, ctx:XplorePathGrammarParser.ExprComparisonForwardContext):
161+
pass
162+
163+
164+
# Enter a parse tree produced by XplorePathGrammarParser#ExprComparisonHit.
165+
def enterExprComparisonHit(self, ctx:XplorePathGrammarParser.ExprComparisonHitContext):
166+
pass
167+
168+
# Exit a parse tree produced by XplorePathGrammarParser#ExprComparisonHit.
169+
def exitExprComparisonHit(self, ctx:XplorePathGrammarParser.ExprComparisonHitContext):
170+
pass
171+
172+
173+
# Enter a parse tree produced by XplorePathGrammarParser#ExprAdditiveForward.
174+
def enterExprAdditiveForward(self, ctx:XplorePathGrammarParser.ExprAdditiveForwardContext):
175+
pass
176+
177+
# Exit a parse tree produced by XplorePathGrammarParser#ExprAdditiveForward.
178+
def exitExprAdditiveForward(self, ctx:XplorePathGrammarParser.ExprAdditiveForwardContext):
179+
pass
180+
181+
182+
# Enter a parse tree produced by XplorePathGrammarParser#ExprAdditiveHit.
183+
def enterExprAdditiveHit(self, ctx:XplorePathGrammarParser.ExprAdditiveHitContext):
184+
pass
185+
186+
# Exit a parse tree produced by XplorePathGrammarParser#ExprAdditiveHit.
187+
def exitExprAdditiveHit(self, ctx:XplorePathGrammarParser.ExprAdditiveHitContext):
188+
pass
189+
190+
191+
# Enter a parse tree produced by XplorePathGrammarParser#ExprMultiplicativeForward.
192+
def enterExprMultiplicativeForward(self, ctx:XplorePathGrammarParser.ExprMultiplicativeForwardContext):
193+
pass
194+
195+
# Exit a parse tree produced by XplorePathGrammarParser#ExprMultiplicativeForward.
196+
def exitExprMultiplicativeForward(self, ctx:XplorePathGrammarParser.ExprMultiplicativeForwardContext):
197+
pass
198+
199+
200+
# Enter a parse tree produced by XplorePathGrammarParser#ExprMultiplicativeHit.
201+
def enterExprMultiplicativeHit(self, ctx:XplorePathGrammarParser.ExprMultiplicativeHitContext):
202+
pass
203+
204+
# Exit a parse tree produced by XplorePathGrammarParser#ExprMultiplicativeHit.
205+
def exitExprMultiplicativeHit(self, ctx:XplorePathGrammarParser.ExprMultiplicativeHitContext):
206+
pass
207+
208+
209+
# Enter a parse tree produced by XplorePathGrammarParser#ExprUnaryNegateHit.
210+
def enterExprUnaryNegateHit(self, ctx:XplorePathGrammarParser.ExprUnaryNegateHitContext):
211+
pass
212+
213+
# Exit a parse tree produced by XplorePathGrammarParser#ExprUnaryNegateHit.
214+
def exitExprUnaryNegateHit(self, ctx:XplorePathGrammarParser.ExprUnaryNegateHitContext):
215+
pass
216+
217+
218+
# Enter a parse tree produced by XplorePathGrammarParser#ExprUnaryLabelHit.
219+
def enterExprUnaryLabelHit(self, ctx:XplorePathGrammarParser.ExprUnaryLabelHitContext):
220+
pass
221+
222+
# Exit a parse tree produced by XplorePathGrammarParser#ExprUnaryLabelHit.
223+
def exitExprUnaryLabelHit(self, ctx:XplorePathGrammarParser.ExprUnaryLabelHitContext):
224+
pass
225+
226+
227+
# Enter a parse tree produced by XplorePathGrammarParser#ExprUnaryPositionHit.
228+
def enterExprUnaryPositionHit(self, ctx:XplorePathGrammarParser.ExprUnaryPositionHitContext):
229+
pass
230+
231+
# Exit a parse tree produced by XplorePathGrammarParser#ExprUnaryPositionHit.
232+
def exitExprUnaryPositionHit(self, ctx:XplorePathGrammarParser.ExprUnaryPositionHitContext):
233+
pass
234+
235+
236+
# Enter a parse tree produced by XplorePathGrammarParser#ExprUnaryForward.
237+
def enterExprUnaryForward(self, ctx:XplorePathGrammarParser.ExprUnaryForwardContext):
238+
pass
239+
240+
# Exit a parse tree produced by XplorePathGrammarParser#ExprUnaryForward.
241+
def exitExprUnaryForward(self, ctx:XplorePathGrammarParser.ExprUnaryForwardContext):
143242
pass
144243

145244

0 commit comments

Comments
 (0)