Scala analisadores de combinadores - distinguir entre cadeias numéricas e cordas variáveis
-
05-07-2019 - |
Pergunta
Estou fazendo exercícios analisador de combinadores de Cay Horstmann, gostaria de saber sobre a melhor maneira de distinguir entre as cordas que representam os números e expressões que representam variáveis ??em uma instrução de correspondência:
def factor: Parser[ExprTree] = (wholeNumber | "(" ~ expr ~ ")" | ident) ^^ {
case a: wholeNumber => Number(a.toInt)
case a: String => Variable(a)
}
A segunda linha lá "caso um: wholeNumber" não é legal. Eu pensei sobre uma expressão regular, mas não encontrei uma maneira de fazê-lo funcionar com o "case".
Solução
Gostaria de dividi-la um pouco e empurre a análise do caso para o |
. Esta é uma das vantagens de combinadores e realmente LL (*) analisar em geral:
def factor: Parser[ExprTree] = ( wholeNumber ^^ { Number(_.toInt) }
| "(" ~> expr <~ ")"
| ident ^^ { Variable(_) } )
Peço desculpas se você não estiver familiarizado com a sintaxe sublinhado. Basicamente isso significa apenas "substituir o n th parâmetro para o valor da função encerrando". Assim { Variable(_) }
é equivalente a { x => Variable(x) }
.
Outra pouco de magia sintaxe aqui é os operadores ~>
e <~
no lugar de ~
. Estes operadores significa que a análise do termo deve incluir o sintaxe de ambos os parênteses, mas o resultado deve ser determinado exclusivamente pelo resultado da expr
. Assim, o "(" ~> expr <~ ")"
corresponde exatamente a mesma coisa que "(" ~ expr ~ ")"
, mas não exige a análise do caso extra para recuperar o valor do resultado interior de expr
.