2012-06-07 3 views
1

Je souhaite analyser certaines affectations, où je me soucie uniquement de l'affectation dans son ensemble. Pas à propos de quoi dans la mission. Une affectation est indiquée par ':='. (EDIT: Avant et après les travaux d'autres choses peuvent venir)Affectations d'analyse ANTLR

Quelques exemples:

a := TRUE & FALSE; 
c := a ? 3 : 5; 
b := case 
      a : 1; 
      !a : 0; 
     esac; 

Actuellement, je fais une différence entre les affectations contenant un « cas » et d'autres missions. Pour les missions simples que j'ai essayé quelque chose comme ~('case' | 'esac' | ';') mais antlr plaignais jetons inégalés (comme '=').

assignment : 
    NAME ':='! expression ; 

expression : 
    (simple_expression | case_expression) ; 


simple_expression : 
    ((OPERATOR | NAME) & ~('case' | 'esac'))+ ';'! ; 

case_expression : 
    'case' .+ 'esac' ';'! ; 

J'ai essayé remplacer par ce qui suit, parce que l'eclipse-interprète ne semble pas aimer le ((OPERATOR | NAME) & ~('case' | 'esac'))+ ';'! ; en raison de la 'and'.

(~(OPERATOR | ~NAME | ('case' | 'esac')) | 
    ~(~OPERATOR | NAME | ('case' | 'esac')) | 
    ~(~OPERATOR | ~NAME | ('case' | 'esac'))) ';'! 

Mais cela ne fonctionne pas. Je reçois

« erreur (139): /AntlrTutorial/src/foo/NusmvInput.g:78:5: complément ensemble est vide | ---> ~ (~ OPÉRATEUR | ~ NOM | ('case' | 'esac'))) EOC!

Comment puis-je l'analyser?

Répondre

2

Il y a deux choses vont mal ici:

  • que vous utilisez dans votre grammaire & alors qu'il devrait être avec guillemets autour de lui: '&'
  • sauf si vous savez exactement ce que vous faites , ne pas utiliser ~ et . (surtout pas .+!) à l'intérieur des règles de l'analyseur: les utiliser dans les règles lexer seulement;
  • créer lexer règles au lieu de définir 'case' et 'esac' dans vos règles d'analyseur (il est sûr d'utiliser des jetons littéraux dans vos règles d'analyseur si aucune autre règle de lexer peut potentiellement match est, mais 'case' et 'esac'regarder beaucoup comme NAMEet ils pourraient se retrouver dans votre AST dans ce cas, il est préférable de les définir explicitement vous-même dans le lexer)

Voici une démonstration rapide:

grammar T; 

options { 
    output=AST; 
} 

tokens { 
    ROOT; 
    CASES; 
    CASE; 
} 

parse 
: (assignment SCOL)* EOF -> ^(ROOT assignment*) 
; 

assignment 
: NAME ASSIGN^ expression 
; 

expression 
: ternary_expression 
; 

ternary_expression 
: or_expression (QMARK^ ternary_expression COL! ternary_expression)? 
; 

or_expression 
: unary_expression ((AND | OR)^ unary_expression)* 
; 

unary_expression 
: NOT^ atom 
| atom 
; 

atom 
: TRUE 
| FALSE 
| NUMBER 
| NAME 
| CASE single_case+ ESAC -> ^(CASES single_case+) 
| '(' expression ')'  -> expression 
; 

single_case 
: expression COL expression SCOL -> ^(CASE expression expression) 
; 

TRUE : 'TRUE'; 
FALSE : 'FALSE'; 
CASE : 'case'; 
ESAC : 'esac'; 
ASSIGN : ':='; 
AND : '&'; 
OR  : '|'; 
NOT : '!'; 
QMARK : '?'; 
COL : ':'; 
SCOL : ';'; 
NAME : ('a'..'z' | 'A'..'Z')+; 
NUMBER : ('0'..'9')+; 
SPACE : (' ' | '\t' | '\r' | '\n')+ {skip();}; 

qui analysera votre entrée:

a := TRUE & FALSE; 
c := a ? 3 : 5; 
b := case 
      a : 1; 
      !a : 0; 
     esac; 

comme suit:

enter image description here

+0

je n'avais pas bien compris la mécanique de l'analyseur et lexer, donc ce que je devrais travailler ^^. Votre solution m'a certainement donné quelques idées, merci. –