2010-02-03 6 views
1

J'ai besoin pour analyser l'interpréteur de commandes telles que:shell de commande de chemin d'analyseur antlr3

cp /home/test /home/test2 

Mon problème est dans l'analyse syntaxique de chemin correct.

Je défini une règle (je ne peux pas utiliser un jeton comme chemin mais je dois définir dans l'analyseur):

path : ('/' ID)+; 

avec

ID: (A.. Z | a.. z) +; 
WS: (' ') {$channel = HIDDEN;}; 

Je dois garder le WS jeton caché, mais cela me donne le problème que les 2 chemins dans cet exemple sont considérés comme un seul chemin.

Comment puis-je résoudre ce problème?

Merci

Répondre

0

Avec un peu de jeu autour de ANTLRWorks j'ai pu obtenir ce travail:

commands 
    : command+ EOF; 

command 
    : (CMD first=path second=path '\n') {System.out.println("Command found, first path:" + $first.text + ", and second path:" + $second.text + "\n");}; 

path : FILE {System.out.println("file is:" + $FILE.text);}; 

fragment 
ID: ('A'..'Z'|'a'..'z')('A'..'Z'|'a'..'z'|'0'..'9')+; 
CMD 
    : ID; 
FILE 
    : ('/' ID)+; 
WS: (' '|'\t'|'\r'|'\n') {$channel = HIDDEN;}; 

S'il vous plaît noter que je devais créer quelques règles supplémentaires de analyseurs lexicaux et commencer à mettre différents analyseur règles à tester. J'ai utilisé une cible java et je vous laisse utiliser ce que vous voulez. Oh oui, chaque commande doit être sur une ligne séparée à cause du '\ n' dans la règle de commande.

+0

Je pense que vous souhaitez étendre la règle de commande maintenant, quelque chose comme: commande: 'cp' premier = chemin d'accès second = chemin '\ n' {...} | 'del' chemin {... vous N'avez qu'un seul chemin pour cette règle à utiliser dans votre action} | 'compare' first = chemin second = chemin third = chemin {placez ici votre code pour comparer le premier avec le second et le lieu dans le troisième}; Bien sûr, cela rendrait également inutile la règle de lexeur CMD (non requise). Mais il pourrait y avoir d'autres façons de faire fonctionner ces travaux. – WayneH

+0

ok, j'apprécie la réponse rapide, mais dans mon cas cela ne fonctionne pas, puisque d'autres règles m'imposent de ne pas définir le chemin comme un jeton (FICHIER). À partir de mon code (avec le chemin NON défini comme un seul jeton), il est possible d'utiliser l'espace (le jeton caché) comme séparateur? – Nio

0

Ok, en fonction de votre commentaire, que diriez-vous quelque chose comme ceci:

commands 
    : command+ EOF; 

command 
    : (ID ' ' (path)+ ' ' (path)+ '\n') {System.out.println("Command found:" + $command.text + "\n");}; 

path : 
    ('/' ID)+ {System.out.println("path is:" + $path.text);}; 

ID: ('A'..'Z'|'a'..'z')('A'..'Z'|'a'..'z'|'0'..'9')+; 
WS: (' '|'\t'|'\r'|'\n') {$channel = HIDDEN;}; 

Encore une fois, je suis en mesure d'obtenir ce travail dans ANTLRWorks rapidement et il semble fonctionner avec la commande cp ci-dessus. Mais pesonally je n'aime pas cela autant puisque votre chemin est une liste de quatre jetons et rapidement je ne pouvais pas me séparer facilement. Donc, vous pourriez avoir besoin d'une règle entre la commande et le chemin (puisque je suppose que votre commande shell peut avoir des commandes qui fonctionnent avec des fichiers alors que d'autres travaillent sur des répertoires). Je souhaite également que les règles d'index et WS lexer soient ce que vous voulez.