2011-01-06 37 views
5

Scala'nın ayrıştırıcı birleştiricileri geriye dönmüyor gibi görünüyor.Scala çözümleyici kombinatorlerinde backtracking?

copy in to out . 

Backtracking ile ayrıştırmak için kolay olmalıdır: Bir dilbilgisi (altta) doğru aşağıdaki "stmt" ayrıştırmak olamaz sahip

stmt: (to out(copy in)) 

veya bir şey eksik?

Ayrıştırıcı:

Sen 2.8'de PackratParsers kullanmak istediğiniz
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

Çalışmaya yaklaştım, şimdi yığın taşması oluyor. Güncelleme ayrıştırıcısı. – Anonymous

cevap

4

. Ben packrat ayrıştırıcı tek backtracking ayrıştırıcı olduğunu düşünüyorum.

Düzenleme: 2015 yılı ortasında, bunun yerine fastparse kullanmalısınız. Sadece çok daha hızlı değil, aynı zamanda kullanımı daha kolay değil (özellikle veri yapılarını ayrıştırmadan oluştururken).

+0

Bu düzeltmek için görünmüyor; Hala SO (sola dönüşlü bir dilbilgisine sahip olmaktan) alıyorum ve paket çözümlemenin bunu düzeltebildiğini duydum. Eğer aramalardan önce değerleri ayrıştırırsam, o zaman ayrıştırılamaz (geri izleme yok mu?). Belki de paket ayrıştırmayı etkinleştirmedim, ancak PackratParsers'ı karıştırmayı ve PakratParser'ı tüm işlevlerden almayı kesinleştirdim. PackratParsers hakkında bir şey biliyor musun? – Anonymous

+1

Oh, tamam, şimdi buldum. Packrat-parsers'a ihtiyaç duyan herkese: "tembel val" ile "def" 'i değiştirmeyi, "Parser [T]" yi "PackratParser [T]" ile değiştirmeyi ve PackratParsers'dan parsers-class/object'i karıştırmayı unutmayın. – Anonymous

+0

@Anonymous Lütfen son talimatınızda daha açık olun: "PackratParsers'dan ayrıştırıcı sınıfı/nesnenin karıştırılması". Bu sadece sınıf için "PackratParsers ile" mi? – javadba

3

Sorununuz geriye dönük değil. scala.util.parsing.combinator'daki standart | operatörü, geri izleme işlemini gerçekleştirecektir. Sorununuz sola dönülmüştür (expr →→ argssmplargsexpr). Packrat ayrıştırma gerçekten bununla yardımcı olabilir.