2010-05-25 5 views
7

J'ai codé un analyseur syntaxique basé sur l'analyseur Scala combinators:Comment améliorer les messages d'erreur dans les analyseurs syntaxiques de l'analyseur syntaxique Scala?

class SxmlParser extends RegexParsers with ImplicitConversions with PackratParsers { 
    [...] 
    lazy val document: PackratParser[AstNodeDocument] = 
     ((procinst | element | comment | cdata | whitespace | text)*) ^^ { 
      AstNodeDocument(_) 
     } 
    [...] 
} 
object SxmlParser { 
    def parse(text: String): AstNodeDocument = { 
     var ast = AstNodeDocument() 
     val parser = new SxmlParser() 
     val result = parser.parseAll(parser.document, new CharArrayReader(text.toArray)) 
     result match { 
      case parser.Success(x, _) => ast = x 
      case parser.NoSuccess(err, next) => { 
       tool.die("failed to parse SXML input " + 
        "(line " + next.pos.line + ", column " + next.pos.column + "):\n" + 
        err + "\n" + 
        next.pos.longString) 
      } 
     } 
     ast 
    } 
} 

En général, les messages d'erreur d'analyse syntaxique qui en résultent sont plutôt bien. Cela arrive parfois

sxml: ERROR: failed to parse SXML input (line 32, column 1): 
`"' expected but `' found 
^ 

Ceci se produit si un guillemet n'est pas fermé et que l'analyseur atteint l'EOT. Ce que j'aimerais voir ici c'est (1) à quelle production se trouvait l'analyseur quand il attendait le '' '(j'en ai plusieurs) et (2) où dans l'entrée cette production commençait à analyser (ce qui est un indicateur Est-ce que quelqu'un sait comment je peux améliorer les messages d'erreur et inclure plus d'informations sur l'état d'analyse interne réel quand l'erreur se produit (peut-être quelque chose comme une règle de production ou tout ce qui peut raisonnablement être identifié ici l'emplacement d'erreur). BTW, la « ligne 32, colonne 1 » ci-dessus est en fait la position EOT et donc d'aucune utilité ici, bien sûr.

Répondre

1

Dans ce cas, vous pouvez utiliser err, failure et ~! des règles de production conçues spécifiquement pour correspondre à l'erreur

3

Je ne sais pas encore comment faire face à (1), mais je cherchais aussi (2) quand je trouve cette page:

https://wiki.scala-lang.org/plugins/viewsource/viewpagesrc.action?pageId=917624

Je simplement copier les informations:

Une amélioration utile consiste à enregistrer la position d'entrée (numéro de ligne et numéro de colonne) des jetons significatifs. Pour ce faire, vous devez faire trois choses:

  • Faire de chaque type de sortie étendre scala.util.parsing.input.Positional
  • appeler la Parsers.positioned() Combinator
  • Utilisez une source de texte que les dossiers positions de ligne et colonne

et

Enfin, assurez-vous que le source suit les positions. Pour les flux, vous pouvez simplement utiliser scala.util.parsing.input.StreamReader; pour les chaînes, utilisez scala.util.parsing.input.CharArrayReader.

Je joue actuellement avec elle, donc je vais essayer d'ajouter un exemple simple plus tard

+0

Maintenant, je peux confirmer que cette façon de le faire est correct (et vraiment simple!). Cela fonctionne parfaitement bien pour moi – Vinz

+0

Lien fourni semble être mort. – jbx

+0

Merci d'avoir signalé le lien mortel, j'ai trouvé une autre source pour la même explication. – Vinz

Questions connexes