2010-01-16 8 views
4

J'ai une grammaire simple LALR (1), mais je rencontre un problème.LALR (1) liste vide des paramètres pour les fonctions

start ::= spec. 
spec ::= MOD STRING top_stmt. 
spec ::= top_stmt. 
top_stmt ::= stmt. 
top_stmt ::= conditional. 
stmt ::= expr. 
stmt ::= assignment. 
conditional ::= IF stmt_list. 
expr ::= retval. 
expr ::= NOT retval. 
retval ::= access. 
retval ::= invoke. 
access ::= ns_identifier OBJECT_OPERATOR property_chain. 
access ::= ns_identifier. 
ns_identifier ::= identifier. 
ns_identifier ::= ns_identifier NS_SEPARATOR identifier. 
ns_identifier ::=. 
property_chain ::= property_chain OBJECT_OPERATOR identifier. 
property_chain ::= identifier. 
identifier ::= VARIABLE. 
identifier ::= STRING. 
assignment ::= access ASSIGN expr. [ASSIGN] 
stmt_list ::= stmt. 
stmt_list ::= stmt_list COMMA stmt. [COMMA] 
invoke ::= access LPAREN empty_stmt_list RPAREN. 
empty_stmt_list ::=. 
empty_stmt_list ::= stmt. 
empty_stmt_list ::= empty_stmt_list COMMA stmt. [COMMA] 

Le point marque la fin de la règle, les bornes entre crochets ont associativité qui leur sont assignées: allouez droit associatif, VIRGULE reste-assoc.

Mais lemon dit qu'il ne peut pas réduire la règle "empty_stmt_list :: =." parce que ce n'est pas connecté au symbole de départ. Je parie que c'est :-)

Il y a aussi un conflit d'analyse pour "invoke", il ne peut pas choisir entre RPAREN et COMMA quand empty_stmt_list est en effet une liste empy d'instructions. Ce que j'essaie de réaliser est d'être en mesure d'analyser les appels de fonction qui n'ont pas de paramètres (vide).

Tout le reste fonctionne comme prévu.

Merci

Modifier: J'ai édité mon message original et affiché toute la grammaire dépouillée.

+0

Votre notation est pas tout à fait conventionnel - est-ce inspiré par ANTLR? Quelles sont les choses entre parenthèses '(A)' et '(B)' Quelle est la signification du seul '.' dans la notation? Il semble être un méta-caractère indiquant la fin de –

Répondre

4

Votre premier problème est que je ne pense pas que ce peu fait ce que vous voulez qu'il:

invoke ::= access LPAREN empty_stmt_list RPAREN. 
empty_stmt_list ::=. 
empty_stmt_list ::= stmt. 
empty_stmt_list ::= empty_stmt_list COMMA stmt. [COMMA] 

La production invoke correspondra access LPAREN COMMA stmt RPAREN, que je suppose est pas souhaitable (et où le LPAREN/Conflit COMMA vient de).

Vous pouvez corriger cela en faisant comme comme celui-ci, qui utilise la règle stmt_list existante:

invoke ::= access LPAREN maybe_empty_stmt_list RPAREN. 
maybe_empty_stmt_list ::= . 
maybe_empty_stmt_list ::= stmt_list. 

qui rend compte encore un conflit (mais seulement 1 maintenant) et se plaint toujours que maybe_empty_stmt_list ::=. ne peut pas reduire. Ainsi, en regardant dans le fichier xxx.out pour voir ce qu'il est:

State 2: 
... 
    (16) ns_identifier ::= * 
... 
    (25) maybe_empty_stmt_list ::= * 
... 
         RPAREN reduce 25 ** Parsing conflict ** 
.... 
        {default} reduce 16 

... il semble que le problème est la règle ns_identifier ::=.. Travailler à travers les productions en cause, il est pas trop difficile de voir qu'un ns_identifier vide peut être réduite à stmt_list (via ns_identifier ->access ->retval ->expr ->stmt ->stmt_list).

Cela explique le conflit; et le fait que la règle ns_identifier ::=. est favorisée dans ce cas parce qu'il apparaît plus tôt dans la grammaire (voir les règles pour résoudre les conflits réduire-réduire dans le documentation explique pourquoi il se plaint que la règle maybe_empty_stmt_list ::=. ne peut jamais être réduite.)

+0

Je l'ai corrigé tout à fait, y compris en supprimant la règle ns_identfier vide qui était en fait un artefact pour résoudre un autre problème plus ancien.Notes à moi-même: la conception de parseurs linguistiques a besoin de soins et de la mentalité «fais-le bien». Réponse acceptée – Flavius

0

Vous pouvez essayer d'ajouter des règles de priorité pour LPAREN/COMMA et vérifier si cela affecte la sémantique dans d'autres endroits.

Questions connexes