2010-03-08 10 views
2

Je suis en train de développer un script en utilisant la bibliothèque de ruby ​​Treetop et j'ai des problèmes de syntaxe pour les regex. Tout d'abord, de nombreuses expressions régulières qui fonctionnent dans d'autres paramètres ne fonctionnent pas de la même manière dans treetop.Utilisation de l'analyse syntaxique de base et de l'expression régulière

C'est ma grammaire: (myline.treetop)

 
grammar MyLine 
    rule line 
     string whitespace condition 
    end 
    rule string 
     [\S]* 
    end 
    rule whitespace 
     [\s]* 
    end 
    rule condition 
     "new"/"old"/"used" 
    end 
end 

Ceci est mon utilisation: (usage.rb)

 
require 'rubygems' 
require 'treetop' 
require 'polyglot' 
require 'myline' 

parser = MyLineParser.new 
p parser.parse("randomstring new") 

Cela devrait trouver le mot nouveau pour vous et il le fait! Maintenant, je ne vais pas l'étendre afin qu'elle puisse trouver de nouvelles si la chaîne d'entrée devient "aléatoire et nouvelle" et éventuellement avoir un nombre quelconque de chaînes suivies par des espaces (onglet inclus) avant et après la regex pour la condition de règle. En d'autres termes, si je lui transmets une phrase contenant le mot "new", il devrait être capable de le faire correspondre.

Alors disons que je change ma grammaire à:

 
rule line 
    string whitespace condition whitespace string 
end 

Ensuite, il devrait être en mesure de trouver un match pour:

p parser.parse("randomstring new anotherstring")

Alors, que dois-je faire pour permettre à la chaîne d'espaces à répéter avant et après condition? Si j'essaie d'écrire ceci:

 
rule line 
    (string whitespace)* condition (whitespace string)* 
end 

, il va dans une boucle infinie. Si je remplace le ci-dessus() par [], il renvoie zéro En général, regex retourne un match quand j'utilise ce qui précède, mais le regex de la cime des arbres ne fait pas. Est-ce que quelqu'un a des conseils/points sur la façon de s'y prendre? De plus, comme il n'y a pas beaucoup de documentation sur la cime des arbres et que les exemples sont soit trop triviaux ou trop complexes, y a-t-il quelqu'un qui connaisse une documentation/un guide plus complet pour cime des arbres?

Répondre

0

Cela n'a rien à voir avec cime des arbres et tout ce qui a trait à votre grammaire. La règle de condition correspond entièrement à votre règle de chaîne. Elle est donc ambiguë lorsque vous passez de la répétition (string whitespace)* à la condition. Nettoyez votre règle de ligne afin d'avoir une grammaire sans ambiguïté et tout ira bien. Vous voudrez peut-être faire en sorte que les choses/attributs comme condition sont étiquetés comme tels:

cond:new 

C'est lexicalement différent de la règle de chaîne.

+1

Merci, je comprends votre point de vue sur la grammaire invalide. Je n'ai pas eu la dernière chose que vous avez dite - "les choses/attributs comme la condition sont marqués comme tels:" .. pouvez-vous expliquer cela plus loin? – user289111

1

On dirait que vous n'avez même pas besoin d'une grammaire pour faire ce que vous demandez. Une regex simple suffit dans ce cas:

line.match(/(.*)\s(new|old|used)\s(.*)/) 

(Exemple: http://rubular.com/r/Kl8rUifxeu)

Vous pouvez obtenir un tableau contenant la substance avant et après l'état avec:

Regexp.last_match(1).split + Regexp.last_match(3) 

et tester les condition avec:

return "Sweet, it's new!" if Regexp.last_match(2) == "new"