나는 논리식의 간단한 파서에 대한 다음 코드를했다 : 그 루트 파서 전체를 구문 분석을 시도Scala PackratParsers는 필요한만큼 역 추적하지 않습니까?
[1.4] failure: string matching regex `\z' expected but `&' found
!a & !b
^
와
import scala.util.parsing.combinator.RegexParsers
import scala.util.parsing.combinator.PackratParsers
object Parsers extends RegexParsers with PackratParsers
// Entities definition
sealed trait LogicalUnit
case class Variable(name: String) extends LogicalUnit
case class Not(arg: LogicalUnit) extends LogicalUnit
case class And(arg1: LogicalUnit, arg2: LogicalUnit) extends LogicalUnit
import Parsers._
// In order of descending priority
lazy val pattern: PackratParser[LogicalUnit] =
((variable) | (not) | (and))
lazy val variable: PackratParser[Variable] =
"[a-zA-Z]".r ^^ { n => Variable(n) }
lazy val not: PackratParser[Not] =
("!" ~> pattern) ^^ { x => Not(x) }
lazy val and: PackratParser[And] =
((pattern <~ "&") ~ pattern) ^^ { case a ~ b => And(a, b) }
// Execution
println(Parsers.parseAll(pattern, "!a & !b"))
그래서, 문자열 !a & !b
을 구문 분석을 시도하고 실패를 보인다 문자열을 pattern -> not -> variable
으로 지정하고 !a
이 아직 끝나지 않았다고 판단되면 다시 추적하지 않으므로 pattern -> and
은 시도조차하지 않았습니다. PackratParsers
을 사용하면 문제를 해결할 수 있다고 생각했지만 그렇지 않았습니다.
일부 문제는 무엇이 잘못 되었습니까?
종합적인 답변 주셔서 감사합니다! 필자는 표준 파서 결합 자의 이러한 한계를 인식하지 못했습니다. 참고로 [GLL 결합 자] (https://github.com/djspiewak/gll-combinators)는이 모호한 사례를 구문 분석하여'! (a &! (b))'와'! (a) &! (b)'로 표시됩니다. –
감사합니다. 예, GLR (및 유사한 GLL) 메서드는 모호성을 처리 할 수 있습니다. PEG는 대안의 순서로 인해 애매 모호하지 않다는 점에 유의하십시오. – inkytonik