Парсеры Scala combinator - различают числовые и переменные строки
-
05-07-2019 - |
Вопрос
Я делаю упражнения синтаксического анализатора Cay Horstmann, мне интересно узнать, как лучше различать строки, представляющие числа, и строки, представляющие переменные в операторе match:
def factor: Parser[ExprTree] = (wholeNumber | "(" ~ expr ~ ")" | ident) ^^ {
case a: wholeNumber => Number(a.toInt)
case a: String => Variable(a)
}
Вторая строка там, " case a: wholeNumber " не законно Я думал о регулярном выражении, но не нашел способа заставить его работать с & Quot; case & Quot;.
Решение
Я бы немного разбил его и вставил анализ случая в |
. Это одно из преимуществ комбинаторов и вообще разбор LL (*):
def factor: Parser[ExprTree] = ( wholeNumber ^^ { Number(_.toInt) }
| "(" ~> expr <~ ")"
| ident ^^ { Variable(_) } )
Я прошу прощения, если вы не знакомы с синтаксисом подчеркивания. По сути, это просто означает & Quot; заменить n th-й параметр значением включающей функции & Quot ;. Таким образом, { Variable(_) }
эквивалентно { x => Variable(x) }
.
Еще одна магия синтаксиса - операторы ~>
и <~
вместо ~
. Эти операторы означают, что синтаксический анализ этого термина должен включать в себя синтаксис обоих символов, но результат должен определяться исключительно результатом expr
. Таким образом, "(" ~> expr <~ ")"
соответствует точно так же, как "(" ~ expr ~ ")"
, но не требует дополнительного анализа кейса для извлечения значения внутреннего результата из <=>.