2009-10-08 9 views
3

J'ai quelques règles de ANTLR que je ne sais pas comment les faire fonctionnerANTLR grammaire ambiguë?

La première règle est la suivante:

STRING_LITERAL 
    : '"' (EscapeSequence | ~('\\'|'"'))* '"' 
    ; 

La deuxième règle est:

element 
: name '=' math_formula ; 
math_formula 
     :  '"' expression '"'; 

L'expression est une expression régulière de type C

Exemple de syntaxe

"count" = "array[3]" 

comptage doit être une chaîne, tandis que array [3] est une expression

Mon problème est que le lexer retourne toujours à la fois « nombre » et « tableau [3] » sous forme de chaînes, et le Parser ne peut pas reconnaître l'expression. J'utilise java target.

EDIT: modification de "variable_name" en "count".

EDIT2: a expliqué ma deuxième tentative ci-dessous:

Je peux détecter le début d'expression avec « = « », mais je ne serai pas en mesure de détecter la fin d'expression dans le Lexer, ce qui fausse détection de chaînes de caractères lorsque j'ai 2 éléments séparés par des « »

"count1" = "array[1]", 
"count2" = "array[2]" 

si je « = « » comme Expression_Début, l'analyseur syntaxique détecté la citation se terminant la première expression, et la citation à partir de la deuxième chaîne de caractères en tant que chaîne ", \ n" qui est évidemment incorrecte.

EDIT 3: Essayer Syntactic prédicats

J'ai changé la règle pour le STRING_LITERAL à

STRING_LITERAL 
    : (~('=') '"' (EscapeSequence | ~('\\'|'"'))* '"')=> '"' (EscapeSequence | ~('\\'|'"'))* '"' 
    ; 

ne fonctionne toujours pas, aussi je ne savais pas comment produire le ~ (» = ') dans la règle elle-même en lui attribuant un label ou quelque chose

Répondre

1

Je ne me souviens plus de la syntaxe maintenant, car cela fait plus de 10 ans, mais l'une des principales forces d'ANTLR est son anticipation arbitraire avec backtracking. Donc, chaque fois que vous voyez une double citation, regardez pour voir si les correspondances element. Si c'est le cas, consommez le flux en tant que element; sinon, revenez à la règle STRING_LITERAL. J'ai repéré dans le guide de référence ANTLR, et trouvé l'exemple de prédicat syntaxique. L'adaptation, je pense que votre règle ressemblerait à quelque chose comme ceci:

protected 
STRING : whatever... 
; 
protected 
EXPRESSION: whatever... 
; 
STRING_OR_EXPR 
: (EXPRESSION) => EXPRESSION { $setType(EXPRESSION); } 
| STRING { $setType(STRING); } 
; 
+0

Le problème que je pense est que l'expression est une règle Parser, tandis que la chaîne est une règle lexer. Ce que vous avez décrit ci-dessus suppose que l'expression EXPRESSION est la règle lexer, ce qui n'est pas le cas. Ou puis-je comprendre quelque chose de mal (débutant dans ANTLR) –

+0

Non, vous avez raison; J'ai oublié cela. Je pense que quelque chose de similaire peut être fait au niveau de l'analyseur. Je vais y regarder un peu plus quand j'ai le temps. – erickson

+0

protégé a été converti en fragment dans ANTLR v3. –

0

Il est difficile de dire, ce que l'analyseur reçoit efficacement, étant donné la façon dont il est affiché sur ce SO page web, et des citations peut-être donnés vous avez ajoutés pour emphaisis.pardonne donc cette supposition de baisc, mais si ANTLR obtient effectivement

"variable_name" = "array[3]" 

(notez les guillemets), cela sonne comme deux jetons séparés STRING_LITERAL par un signe égal pour lequel il n'a probablement pas de règle.

variable_name = "array[3]" 

ou peut-être mieux

variable_name = array[3] 

est ce que vous essayez de faire.

EDIT:
Après avoir éclairci ce nom est un STRING (défini ailleurs, sans les guillemets), il son clair que les hypothèses ci-dessus sont « commencent à » être correct. Cependant, un autre problème est que, à moins que expression est définie avec des caractères interdits dans un STRING_LITTERAL, math_formula sera ambiguë avec elle, et par conséquent le lexer ne verra pas un élément mais une séquence "name '=' STRING_LITERAL" pour laquelle elle n'a pas de règles.

+0

Non, les citations font correctement partie de la syntaxe du langage –

+0

et Mon problème est tel que vous l'avez décrit, ANTLR lexer renvoie deux STRING_LITERAL en raison des citations –

+0

@unknown Je vois que math_formula fait, mais quoi de nom? Quelle est la règle pour le nom? Est-ce qu'il inclut aussi des guillemets, et le contenu entre guillemets diffère-t-il de ce qui serait une expression valide? – mjv

0

Quel genre de langage vis-à-vis essayez-vous d'analyser? Je parierais que votre meilleur pari est d'ajouter un état à votre lexer le long de ces lignes:

ASSIGN: 
    ('=' '"')=> /* assuming whitespace doesn't exist */ 
    '=' {some_global_flaggy_thing=1;} 
    |'=' 
    ; 
STRING_LITERAL: 
    {some_global_flaggy_thing==1}? '"' {$type=QUOTE; some_gobal_flaggy_thing=2;} 
    |{some_global_flaggy_thing==2}? '"' {$type=QUOTE; some_global_flaggy_thing=0;} 
    | '"' /* normal string literal stuff */ '"' 
    ; 

Bien sûr, votre expression intégré ne peux pas avoir des chaînes littérales en elle.
Remarque Je suis plus familier avec ANTLR2

Questions connexes