2010-03-09 13 views
0

J'ai une configuration simple de la grammaire comme ceci:questions de grammaire arboricoles en utilisant des expressions régulières

 
grammar Test 
    rule line 
     (adjective/not_adjective)* { 
     def content 
      elements.map{|e| e.content } 
     end 
     } 
    end 
    rule adjective 
     ("good"/"bad"/"excellent") { 
      def content 
       [:adjective, text_value] 
      end 
     } 
    end 
    rule not_adjective 
     !adjective { 
      def content 
       [:not_adjective, text_value] 
      end 
     } 
    end 
end 

Disons que mon entrée est «c'est une belle passe, nous allons l'utiliser. ». Cela donne une erreur, que je ne mentionne pas en ce moment parce que je veux comprendre la théorie sur la raison pour laquelle elle a tort en premier. Alors, comment puis-je créer une règle not_adjective afin qu'elle corresponde à tout ce qui ne correspond pas à l'adjectif de la règle? En général, comment écrire je règle (spécifiquement dans Treetop) qui "ne correspond pas" à une autre règle nommée?

Répondre

1

Treetop est un parser generator qui génère des analyseurs syntaxiques à partir d'une classe spéciale de grammaires appelée Parsing Expression Grammars or PEG.
L'interprétation opérationnelle de !expression est qu'il réussit si expression échoue et échoue si expression réussit mais consomme NO entrée.
Pour correspondre à quelque chose que la règle expression ne correspond pas à utiliser l'opérateur dot (qui correspond à quoi que ce soit) conjointement avec l'opérateur de négation pour éviter certains « mots »:

(!expression .)* ie. "match anything BUT expression" 
1

La réponse précédente est incorrecte pour de l'OP question, car il va correspondre à n'importe quelle séquence de caractères individuels jusqu'à n'importe quel adjectif. Donc, si vous voyez la chaîne xyzgood, elle correspond à xyz et une règle suivante correspondra à la "bonne" partie en tant qu'adjectif. De même, la règle adjective de l'OP correspondra aux trois premiers caractères de "badge" comme l'adjectif "mauvais", ce qui n'est pas ce qu'ils veulent.

Au lieu de cela, la règle de l'adjectif devrait ressembler à ceci:

rule adjective 
    a:("good"/"bad"/"excellent") ![a-z] { 
    def content 
     [:adjective, a.text_value] 
    end 
    } 
end 

et la règle not_adjective comme ceci:

rule not_adjective 
    !adjective w:([a-z]+) { 
    def content 
     [:not_adjective, w.text_value] 
    end 
    } 
end 

comprennent la manipulation des majuscules, césures, apostrophes, etc, nécessaire. Bien sûr, vous aurez également besoin d'une manipulation en espace blanc.