2011-05-21 2 views
2

abord, le code:quelques problèmes simples avec Scala Combinator parseurs

package com.digitaldoodles.markup 

import scala.util.parsing.combinator.{Parsers, RegexParsers} 
import com.digitaldoodles.rex._ 


class MarkupParser extends RegexParsers { 
    val stopTokens = (Lit("{{") | "}}" | ";;" | ",,").lookahead 
    val name: Parser[String] = """[@#!$]?[a-zA-Z][a-zA-Z0-9]*""".r 
    val content: Parser[String] = (patterns.CharAny ** 0 & stopTokens).regex 
    val function: Parser[Any] = name ~ repsep(content, "::") <~ ";;" 
    val block1: Parser[Any] = "{{" ~> function 
    val block2: Parser[Any] = "{{" ~> function <~ "}}" 
    val lst: Parser[Any] = repsep("[a-z]", ",") 
} 

object ParseExpr extends MarkupParser { 
    def main(args: Array[String]) { 
     println("Content regex is ", (patterns.CharAny ** 0 & stopTokens).regex) 
     println(parseAll(block1, "{{@name 3:4:foo;;")) 
     println(parseAll(block2, "{{@name 3:4:foo;; stuff}}")) 
     println(parseAll(lst, "a,b,c")) 
    } 
} 

puis, les résultats d'exécution:

[info] == run == 
[info] Running com.digitaldoodles.markup.ParseExpr 
(Content regex is ,(?:[\s\S]{0,})(?=(?:(?:\{\{|\}\})|;;)|\,\,)) 
[1.18] parsed: (@name~List(3:4:foo)) 
[1.24] failure: `;;' expected but `}' found 

{{@name 3:4:foo;; stuff}} 
        ^

[1.1] failure: string matching regex `\z' expected but `a' found 

a,b,c 
^ 

-je utiliser une bibliothèque personnalisée pour assembler certains de mes expressions rationnelles, donc je ai imprimé l'expression rationnelle "content"; Il est censé être essentiellement n'importe quel texte jusqu'à, mais ne comprenant pas certains modèles de jetons, imposé en utilisant une assertion positive.

Enfin, les problèmes:

1) La première course sur « block1 » réussit, mais ne devrait pas, parce que le séparateur dans la fonction « repsep » est « :: », mais « : » sont analysées en tant que séparateurs.

2) L'exécution sur "block2" échoue, sans doute parce que la clause lookahead ne fonctionne pas - mais je ne peux pas comprendre pourquoi cela devrait être. La clause lookahead était déjà exercée dans le "repsep" sur "run1" et semblait fonctionner là, alors pourquoi devrait-elle échouer sur le bloc 2? 3) L'exercice de repsep simple sur "lst" échoue parce qu'en interne, le moteur de l'analyseur semble chercher une limite - est-ce quelque chose dont j'ai besoin pour contourner le problème?

Merci, Ken

Répondre

2

1) Non, "::" ne sont pas analysées comme séparateurs. Si c'était le cas, la sortie serait (@name~List(3, 4, foo)).

2) Il se produit parce que "}}" est également un délimiteur, donc il prend la plus longue correspondance possible - celle qui comprend ";;" ainsi. Si vous rendez l'expression précédente non désirée, elle échouera alors à "s" sur "stuff", ce que je suppose être ce que vous attendiez.

3) Vous avez passé un littéral, pas une regex. Modifiez "[a-z]" à "[a-z]".r et cela fonctionnera.

Questions connexes