2010-10-25 20 views
2

Je me suis peut-être posé une question stupide/de base mais j'avais été confus au sujet du bâtiment ANTLR AST. Ce que je veux faire est une sorte d'analyseur d'expressions booléennes tel que sur les nœuds parents j'ai l'opérateur et ses opérandes en tant qu'enfants. par exemple, une phraseANTLR Bâtiment AST: nœud racine en tant que chaîne à la place du caractère

((A B C & D) | (E & (F | G)))

devrait idéalement être représentant

   | 
      /\ 
      / \ 
     / \ 
     /  \ 
     &   & 
     /\  /\ 
    / \ / \ 
    / D E  | 
    /|\   /\ 
    A B C   / \ 
        F  G 

De la grammaire suivante.

grammar Test; 

options 
{ 
    language = 'Java'; 
    output=AST; 
} 


exp : word (expRest^)? | '('! exp ')'! (expRest^)? ; 

expRest : (('&'|'|'|'!'|'&!'|'|!')^) exp | (('~'^) digit+ exp); 
word : letter letter* -> ^(letter letter*); 
letter :  '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'|'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j'|'k'|'l'|'m'|'n'|'o'|'p'|'q'|'r'|'s'|'t'|'u'|'v'|'w'|'x'|'y'|'z'|'A'|'B'|'C'|'D'|'E'|'F'|'G'|'H'|'I'|'J'|'K'|'L'|'M'|'N'|'O'|'P'|'Q'|'R'|'S'|'T'|'U'|'V'|'W'|'X'|'Y'|'Z'; 
digit : '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'; 

Le problème est que je reçois « A B C » soit comme une liste (tableau) des noeuds comme des enfants de « & ». Est-il possible de le restreindre comme une seule chaîne??

c'est-à-dire 'A B C' ou en d'autres termes, est-il possible d'avoir plusieurs caractères au nœud racine dans AST ??? Si oui, comment puis-je y arriver?

pour référence, je veux faire un arbre de syntaxe des « facteurs de risques & état économique actuel »

post-scriptum J'ai aussi essayé:

word : (letter letter*)^ ; 

Et pour une référence, je suis en utilisant l'environnement .NET.

+0

Vous avez 'language = 'Java';' dans votre grammaire, mais vous dites * "... J'utilise l'environnement .NET" * –

+0

désolé pour cela, en fait je le fais 'CSharp' chaque fois que je génère du code. Fait intéressant, j'allais ajouter un commentaire mais j'ai vu le vôtre:) ... Merci. – Umer

Répondre

3

Vous pouvez insérer des jetons imaginaires dans votre grammaire qui seront la racine de "groupes" de mots. Je ne pense pas que c'est une bonne idée de coller le A, B et C ensemble puisque vous avez probablement besoin d'eux séparés, non?

Je ne pouvais pas vraiment comprendre ce que vous avez tout à fait d'essayer de le faire, alors voici une petite démo que vous pouvez (essayer de) obtenir autour de votre tête:

grammar BoolExp; 

options { 
    output=AST; 
} 

tokens { 
    MultiWord; 
} 

parse 
    : booleanExp EOF! 
    ; 

booleanExp 
    : orExp 
    ; 

orExp 
    : andExp ('|'^ andExp)* 
    ; 

andExp 
    : notExp ('&'^ notExp)* 
    ; 

notExp 
    : '!'^ atom 
    | atom 
    ; 

atom 
    : '(' booleanExp ')' -> booleanExp 
    | WORD WORD+   -> ^(MultiWord WORD+) 
    | WORD 
    ; 

WORD 
    : ('a'..'z' | 'A'..'Z')+ 
    ; 

SPACE 
    : (' ' | '\t' | '\r' | '\n'){skip();} 
    ; 

Si vous générez un analyseur de celui-ci et le tester avec l'entrée:

((A B C & D) | (E & (F | G))) 

vous obtiendrez l'AST suivante:

alt text

Je n'ai pas posté mon (Java) classe de test qui a généré le fichier DOT qui a été utilisé pour créer l'image AST ci-dessus puisque vous avez dit que vous utilisez le .NET cible. Si vous voulez y jeter un coup d'œil, laissez un commentaire et je le posterai aussi.

+0

Je suppose que ça va marcher mais laissez-moi essayer et vous le faire savoir. Y at-il une différence dans le mot que j'ai utilisé et «WORD» que vous utilisez ??? Quand j'ai utilisé 'WORD', il était de couleur bleue au lieu de rouge (contrairement aux autres terminaux). – Umer

+1

Je suppose que vous voulez dire que certaines règles sont colorées en bleu et en rouge ANTLRWorks, n'est-ce pas? (N'a pas utilisé ANTLRWorks dans un long moment). Les règles commençant par un capital sont des règles lexer, celles qui commencent par une lettre minuscule sont des règles d'analyseur. HTH. –

+0

ahhh, à droite. Génial. En fait, l'indice MultiWord a fait l'affaire. Je sélectionne tous les enfants comme espace séparé chaque fois qu'il y a un texte multi-mots comme texte de noeud et que les enfants sont des signes de tête de feuille. Merci de m'avoir aidé. – Umer

0

Si vous voulez « A B C » comme un seul noeud, puis définissez lettre pour inclure « » entre les personnages tels que:

letter : character (space character)*; 
character : '0'..'9'|'a'..'z'|'A'..'Z'; 
space : ' '; 

qui comprendra des espaces que les enfants du nœud lettre.

+0

apparemment, il n'y avait aucun problème en écrivant au-dessus de la grammaire, mais je suis incapable de déboguer avec au-dessus de la grammaire. Je ne sais pas ce qui ne va pas avec ça ... (j'utilise ANTLRWorks 1.4 pour le débogage) – Umer