2011-01-20 2 views
2

Je suis assez familier avec Antlr 2.X et les cibles Anthar 3.1.X CSharp et python.Quel est l'équivalent d'exécution Antlr3 C de lancer une exception pour le rapport d'erreurs

Cependant, je suis maintenant obligé d'utiliser la cible Antlr 3 C pour un projet.

Mon problème est de savoir comment signaler les erreurs dans ma grammaire ou grammaire d'arborescence. Considérons une règle qui correspond à un jeton et que nous l'avons placée dans une carte. Nous voulons nous assurer que le jeton est unique. Normalement, je lance une exception si le jeton est déjà dans la carte et attrape l'exception en dehors de l'analyseur syntaxique pour signaler l'erreur.

Quel est l'équivalent d'exécution de Antlr C de la règle suivante?

token_match: ID 
{ 
    if(mp.find($ID.Text)) 
     throw std::exception("Non unique token found"); 
} 

Répondre

1

Je vous recommande d'utiliser vos propres méthodes pour afficher les erreurs sémantiques. Mais si vous devez rester dans ANTLR pour cela:

Vous devez d'abord créer votre propre gestionnaire d'erreur si vous voulez créer des types d'exception personnalisés. Regardez antlr3baserecognizer.c: 1000 pour l'original. Ensuite, codez une fonction ou un code de règle pour traiter une structure d'exception.

static void   
displayRecognitionErrorNew (pANTLR3_BASE_RECOGNIZER recognizer, 
          pANTLR3_UINT8 * tokenNames) 
{ 
... 
    switch (ex->type) 
    { 
    case ANTLR3_UNWANTED_TOKEN_EXCEPTION: 
... 
    case NUTF_EXCEPTION: 
     printf("Non unique token found"); 
     break; 
Regardez antlr3baserecognizer.c: 325 pour configurer votre exception.

ex = antlr3ExceptionNew(ANTLR3_RECOGNITION_EXCEPTION, 
         (void *)ANTLR3_RECOGNITION_EX_NAME, 
         NULL, 
         ANTLR3_FALSE); 

ex->type    = NUTF_EXCEPTION 
ex->line    = ins->getLine (ins); 
ex->charPositionInLine = ins->getCharPositionInLine (ins); 
ex->index    = is->index (is); 
ex->streamName   = ins->fileName; 
ex->message    = "That was totally unexpected"; 

Ensuite, vous devez lancer votre exception lorsque vous détectez l'erreur. Je pense que la seule façon de le faire est de surcharger mismatch() en ajoutant votre code et en l'appelant à partir de votre règle.

static void 
mismatchNew(pANTLR3_BASE_RECOGNIZER recognizer, ANTLR3_UINT32 ttype, pANTLR3_BITSET_LIST follow) 
{ 
    ... 
} 

Enfin, dites à ANTLR d'utiliser vos nouvelles fonctions.

@parser::apifuncs { 
    RECOGNIZER->displayRecognitionError  = displayRecognitionErrorNew; 
    RECOGNIZER->antlr3RecognitionExceptionNew = antlr3RecognitionExceptionNewNew; 
    RECOGNIZER->mismatch      = mismatchNew; 
} 
+0

Merci pour la réponse. Juste une note, mon problème n'est pas de surcharger ces membres, cela a été fait :) Ma question est avec ma propre validation en code natif. Lancer une exception est-il la bonne façon de signaler une erreur? – chollida

Questions connexes