2017-07-25 2 views
1

J'essaie de faire une grammaire ANTLR pour une donnée, qui contient une partie, où je peux passer NewLine, et une partie, où cela peut être important. Plus précisément, je suis intéressé à sauter NewLine entre parenthèses et que vous voulez réaliser qu'en utilisant les modes lexer. Mais il y a le problème: en DEFAULT_MODE il y a beaucoup de règles lexer, et les jetons, qui sont décrits dans ces règles, peuvent apparaître à l'intérieur de parenthèses aussi. Comment puis-je résoudre le problème?ANTLR: Sauter NewLine en fonction du contexte sans utiliser les actions

Peut-être que l'état actuel de mon code vous aidera à comprendre la question

// ... 

LPAREN : '(' -> pushMode(InsideParen) ; 

// ... 

mode InsideParen ; 
InsideParenNewLine : ('\r'? '\n') -> skip ; 

// here I want somehow recognize all tokens from DEFAULT_MODE without rewriting all rules 

RPAREN: ')' -> popMode ; 

Merci à l'avance.

+0

Ceci est ANTLR3? Ou voulez-vous faire ces actions dans ANTLR4? – TomServo

+0

@JLH C'est ANTLR3 – sibstudent1

+0

Je suis un gars ANTLR4. Cependant, le comportement dont vous parlez est similaire à la façon dont Python traite les espaces. Suggérez-vous de rechercher une grammaire ANTL3 Python et de prendre quelques conseils à ce sujet. Il doit y en avoir un là-bas. Bonne chance! – TomServo

Répondre

0

Dès que j'ai vu cette question, j'ai pensé que votre problème ressemblait à celui de la gestion de retour à la ligne Python. Mais je remarqué que vous utilisiez pushMode, ce qui est un ANTLR4 construire ...

Si vous êtes prêt à vous mise à niveau ANTLR4 cependant, vous pouvez profiter de choses comme:

LINENDING:    (('\r'? '\n')+ {self._lineContinuation=False} 
    |  '\\' [ \t]* ('\r'? '\n') {self._lineContinuation=True}) 
{ 
if self._openBRCount == 0 and not self._lineContinuation: 
    if not self._suppressNewlines: 
     self.emitNewline() 
     self._suppressNewlines = True 
    la = self._input.LA(1) 
    if la not in [ord(' '), ord('\t'), ord('#')]: 
     self._suppressNewlines = False 
     self.emitFullDedent() 
} -> channel(HIDDEN) 
    ; 

OPEN_PAREN:  '(' {self._openBRCount += 1}; 
CLOSE_PAREN: ')' {self._openBRCount -= 1}; 
OPEN_BRACE:  '{' {self._openBRCount += 1}; 
CLOSE_BRACE: '}' {self._openBRCount -= 1}; 
OPEN_BRACKET: '[' {self._openBRCount += 1}; 
CLOSE_BRACKET: ']' {self._openBRCount -= 1}; 

UNKNOWN: . -> skip; 

Cela fera votre grammaire agit comme Python en ce qui concerne les espaces, et peut-être quelques réglages où vous agissez sur parenthese au lieu de caractères de continuation de ligne. Voir this python grammar.