2011-01-06 9 views
5

Parece que los combinadores de analizadores scala no retroceden. Tengo una gramática (ver abajo), que no puede analizar el siguiente "prop" correctamente:¿Retroceso en los combinadores scala parser?

copy in to out . 

Eso debería ser fácil de analizar con retroceso:

stmt: (to out(copy in)) 

o me estoy perdiendo algo?

Analizador:

type ExprP = Parser[Expr] 
type ValueP = Parser[ValExpr] 
type CallP = Parser[Call] 
type ArgsP = Parser[Seq[Expr]] 

val ident  = "[a-zA-Z\\+\\-\\*/%><\\\\\\=]+".r 
val sqstart = "\\["       .r 
val sqend  = "\\]"       .r 
val del  = ","       .r 
val end  = "\\."       .r 

def stmt: ExprP  = expr <~ end 
def expr: ExprP  = ucall | call | value 
def value: ValueP = ident ^^ {str => IdentExpr(str)} 
def call: CallP  = (args ~ ident ~ expr) ^^ {case args ~ method ~ upon => Call(args, method, upon)} 
def ucall: CallP  = (ident ~ expr) ^^ {case method ~ upon => Call(Seq(), method, upon)} 
def args: ArgsP  = advargs | smplargs 
def smplargs: ArgsP = expr ^^ {e => Seq(e)} 
def advargs: ArgsP = (sqstart ~> repsep(expr, del) <~ sqend) ^^ {seq => seq} 
+0

Lo tengo cerca de funcionar, ahora recibo un desbordamiento de pila. Analizador actualizado – Anonymous

Respuesta

4

Desea utilizar PackratParsers en 2.8. Creo que el analizador packrat es el único analizador de retroceso.

Editar: a partir de mediados de año 2015, debe utilizar fastparse en su lugar. No solo es mucho más rápido, sino también más fácil de usar (especialmente cuando se construyen estructuras de datos a partir del análisis sintáctico).

+0

Parece que no lo arregla; Sigo recibiendo SO (por tener una gramática recursiva a la izquierda), y escuché que el análisis de packrat debería poder arreglar eso. Si hago que analice los valores antes de las llamadas, entonces no se analizará (¿no retrocede?). Tal vez no he activado el análisis de paquetes, pero me aseguré de mezclar los PackratParsers y devolver PakratParser de todas las funciones. ¿Sabes algo sobre PackratParsers? – Anonymous

+1

Oh, está bien, ahora lo encontré. Para todos los que necesiten packrat-parsers: recuerden reemplazar "def" por "perezoso val", reemplazar "Parser [T]" por "PackratParser [T]" y crear la clase de mezcla de analizadores y objetos de PackratParsers. – Anonymous

+0

@Anonymous Sea más claro con su última instrucción: "crear la clase de mezcla de objetos/clase de analizadores de PackratParsers". ¿Es simplemente "con PackratParsers" para la clase? – javadba

3

Tu problema no es retroceder. El operador estándar | en scala.util.parsing.combinator hará un backtracking. Su problema es recursión a la izquierda (exprcallargssmplargsexpr). El análisis de Packrat puede ayudar con eso.

Cuestiones relacionadas