Analizadores combinadores de Scala: distinguen entre cadenas numéricas y cadenas variables

StackOverflow https://stackoverflow.com/questions/256694

  •  05-07-2019
  •  | 
  •  

Pregunta

Estoy haciendo los ejercicios del analizador combinador de Cay Horstmann. Me pregunto cuál es la mejor manera de distinguir entre cadenas que representan números y cadenas que representan variables en una declaración de coincidencia:

def factor: Parser[ExprTree] = (wholeNumber | "(" ~ expr ~ ")" | ident) ^^ {
    case a: wholeNumber  => Number(a.toInt)
    case a: String => Variable(a)
}

La segunda línea allí, "caso a:WholeNumber" no es legal.Pensé en una expresión regular, pero no encontré una manera de hacer que funcione con "case".

¿Fue útil?

Solución

Lo dividiría un poco y llevaría el análisis del caso al |.Esta es una de las ventajas de los combinadores y del análisis LL(*) en general:

def factor: Parser[ExprTree] = ( wholeNumber ^^ { Number(_.toInt) }
                               | "(" ~> expr <~ ")" 
                               | ident ^^ { Variable(_) } )

Pido disculpas si no está familiarizado con la sintaxis del guión bajo.Básicamente simplemente significa "sustituir el norteº parámetro al valor de la función circundante".De este modo { Variable(_) } es equivalente a { x => Variable(x) }.

Otro poco de magia sintáctica aquí es el ~> y <~ operadores en lugar de ~.Estos operadores significan que el análisis de ese término debe incluir el sintaxis de ambos padres, pero el resultado debe ser determinado únicamente por el resultado de expr.Por lo tanto, la "(" ~> expr <~ ")" coincide exactamente con lo mismo que "(" ~ expr ~ ")", pero no requiere el análisis de caso adicional para recuperar el valor del resultado interno de expr.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top