This is my grammar:
@skip { spaces }
@precedence {
times @left,
plus @left,
and @left,
or @left
}
@top Pipeline {
state ("|" state)*
}
state {
MatchState
}
MatchState {
"match:" matchCondition
}
matchCondition {
AndCondition | OrCondition | EqCondition | GtCondition | GeCondition | LtCondition | LeCondition | ParenthesizedCondition
}
AndCondition {
matchCondition !and "and" matchCondition
}
OrCondition {
matchCondition !or "or" matchCondition
}
NotCondition {
NotOp matchCondition
}
EqCondition {
expression EqOp (logicalExpression | expression)
}
GtCondition {
expression GtOp expression
}
GeCondition {
expression GeOp expression
}
LtCondition {
expression LtOp expression
}
LeCondition {
expression LeOp expression
}
ParenthesizedCondition { "(" matchCondition ")" }
logicalExpression[@isGroup=LogicalExpression] {
AndLogicalExpression | OrLogicalExpression | ParenthesizedLogicalExpression
}
AndLogicalExpression {
(expression | logicalExpression) !and "and" (expression | logicalExpression)
}
OrLogicalExpression {
(expression | logicalExpression) !or "or" (expression | logicalExpression)
}
ParenthesizedLogicalExpression { "(" logicalExpression ")" }
expression[@isGroup=Expression] {
Number |
String |
Identifier |
@specialize[@name=BooleanLiteral]<Identifier, "true" | "false"> |
RegExp |
ArrayExpression {
"[" commaSep1<"..."? expression | ""> "]"
} |
UnaryExpression |
ParenthesizedExpression |
BinaryExpression
}
//!commaSep
commaSep<content> {
(content ("," content)*)?
}
commaSep1<content> {
content ("," content)*
}
ParenthesizedExpression { "(" expression ")" }
//!operators
UnaryExpression {
ArithOp<"+" | "-">
expression
}
BinaryExpression {
expression !times (ArithOp<"/"> | ArithOp<"%"> | ArithOp<"*">) expression |
expression !plus ArithOp<"+" | "-"> expression
}
@tokens {
spaces[@export] { $[\u0009 \u000b\u00a0]+ }
newline[@export] { $[\r\n] }
identifierChar { @asciiLetter | $[_$\u{a1}-\u{10ffff}] }
Identifier { identifierChar (identifierChar | @digit)* }
//!numberTokens
hex { @digit | $[a-fA-F] }
Number {
(@digit ("_" | @digit)* ("." ("_" | @digit)*)? | "." @digit ("_" | @digit)*)
(("e" | "E") ("+" | "-")? ("_" | @digit)+)? |
@digit ("_" | @digit)* "n" |
"0x" (hex | "_")+ "n"? |
"0b" $[01_]+ "n"? |
"0o" $[0-7_]+ "n"?
}
@precedence { Number "." }
//!stringTokens
String {
'"' (![\\\n"] | "\\" _)* '"'? |
"'" (![\\\n'] | "\\" _)* "'"?
}
//!operatorTokens
ArithOp<expr> { expr }
NotOp { "not" }
EqOp { "=" }
LtOp { "<" }
LeOp { "<=" }
GtOp { ">" }
GeOp { ">=" }
PipeOp { "|" }
//!regexpTokens
RegExp { "/" (![/\\\n[] | "\\" ![\n] | "[" (![\n\\\]] | "\\" ![\n])* "]")+ ("/" $[gimsuy]*)? }
//!literalTokens
"=" "..." "=>"
"(" ")" "[" "]" "{" "}"
"." "," ";" ":"
}
I want this
match: people = 3 or (people = 4 or animal < (people +4) * 4 / money)
to be parsed as
match: (people = 3) or (people = 4 or animal < (people +4) * 4 / money)
which means
MatchState
OrCondition
EqCondition
ParenthesizedCondition
However, currently it is parsed as
match: people = (3 or (people = 4 or animal < (people +4) * 4 / money))
which means
MatchState
Identifier
EqOp
OrLogicalExpression
I know it’s ambiguous。 But according to the documentation lezer supports branch matching. I’ve tried many combinations and still haven’t tried to figure out where the disambiguation markers should be placed to achieve this effect