解析搜索表达式上的括号 - Scala 解析器组合器
Parsing parentheses on search expression - Scala parser combinator
我正在为搜索表达式编写解析器。
例如
a = "zyx" and ( b < 5 or c > 9)
我写了这个解析器,但它无法匹配括号,得到这个错误:
failure: identifier expected
a = "zyx" and ( b < 5 or c > 9)
^
我该怎么做才能匹配括号
class SearchQueryParser extends StandardTokenParsers {
def expr: Parser[Expression] = orExp | "(" ~> orExp ~ ")"
def orExp: Parser[Expression] = {
andExp *("or" ^^^ {(a: Expression, b: Expression) => BoolExp("OR", (a, b))})
}
def andExp: Parser[Expression] = {
compareExp *("and" ^^^ {(a: Expression, b: Expression) => BoolExp("AND", (a, b))})
}
def compareExp: Parser[Expression] = {
identifier ~ rep(
("=" | "!=" | "<" | ">") ~ literal ^^ {
case op ~ rhs => (op, rhs)
}
) ^^ {
case (acc, ("=", rhs: Expression)) => Binomial("=", acc, rhs)
case (acc, ("!=", rhs: Expression)) => Binomial("!=", acc, rhs)
case (acc, ("<", rhs: Expression)) => Binomial("<", acc, rhs)
case (acc, (">", rhs: Expression)) => Binomial(">", acc, rhs)
}
}
}
您当前的语法只允许在 expr
规则中使用括号,我认为这是您的主要规则,并且 expr
规则从未被任何其他规则使用。所以括号只能包含在整个表达式中。
你想要做的是将 "(" ~ expr ~ ")"
放在允许括号表达式的最低位置。据我了解你的语法,这可能意味着允许它作为 andExp
中 compareExp
的替代(假设你不想在 compareExp
s 中使用括号)。
如@sepp2k 所述,您需要将括号放在允许使用括号的最低位置。在你的情况下,它应该在 compareExp:
def compareExp: Parser[Expression] = {
"(" ~> expr <~ ")" | identifier ~ rep(
("=" | "!=" | "<" | ">") ~ literal ^^ {
case op ~ rhs => (op, rhs)
}
) ^^ {
case (acc, ("=", rhs: Expression)) => Binomial("=", acc, rhs)
case (acc, ("!=", rhs: Expression)) => Binomial("!=", acc, rhs)
case (acc, ("<", rhs: Expression)) => Binomial("<", acc, rhs)
case (acc, (">", rhs: Expression)) => Binomial(">", acc, rhs)
}
}
和 exp
方法不应处理括号
def expr: Parser[Expression] = orExp
我正在为搜索表达式编写解析器。 例如
a = "zyx" and ( b < 5 or c > 9)
我写了这个解析器,但它无法匹配括号,得到这个错误:
failure: identifier expected
a = "zyx" and ( b < 5 or c > 9)
^
我该怎么做才能匹配括号
class SearchQueryParser extends StandardTokenParsers {
def expr: Parser[Expression] = orExp | "(" ~> orExp ~ ")"
def orExp: Parser[Expression] = {
andExp *("or" ^^^ {(a: Expression, b: Expression) => BoolExp("OR", (a, b))})
}
def andExp: Parser[Expression] = {
compareExp *("and" ^^^ {(a: Expression, b: Expression) => BoolExp("AND", (a, b))})
}
def compareExp: Parser[Expression] = {
identifier ~ rep(
("=" | "!=" | "<" | ">") ~ literal ^^ {
case op ~ rhs => (op, rhs)
}
) ^^ {
case (acc, ("=", rhs: Expression)) => Binomial("=", acc, rhs)
case (acc, ("!=", rhs: Expression)) => Binomial("!=", acc, rhs)
case (acc, ("<", rhs: Expression)) => Binomial("<", acc, rhs)
case (acc, (">", rhs: Expression)) => Binomial(">", acc, rhs)
}
}
}
您当前的语法只允许在 expr
规则中使用括号,我认为这是您的主要规则,并且 expr
规则从未被任何其他规则使用。所以括号只能包含在整个表达式中。
你想要做的是将 "(" ~ expr ~ ")"
放在允许括号表达式的最低位置。据我了解你的语法,这可能意味着允许它作为 andExp
中 compareExp
的替代(假设你不想在 compareExp
s 中使用括号)。
如@sepp2k 所述,您需要将括号放在允许使用括号的最低位置。在你的情况下,它应该在 compareExp:
def compareExp: Parser[Expression] = {
"(" ~> expr <~ ")" | identifier ~ rep(
("=" | "!=" | "<" | ">") ~ literal ^^ {
case op ~ rhs => (op, rhs)
}
) ^^ {
case (acc, ("=", rhs: Expression)) => Binomial("=", acc, rhs)
case (acc, ("!=", rhs: Expression)) => Binomial("!=", acc, rhs)
case (acc, ("<", rhs: Expression)) => Binomial("<", acc, rhs)
case (acc, (">", rhs: Expression)) => Binomial(">", acc, rhs)
}
}
和 exp
方法不应处理括号
def expr: Parser[Expression] = orExp