2017-07-13 3 views
0

J'ai un problème sérieux au sujet de l'expression |.ANTLR 'ou' expression régulière

Ma grammaire contient une expression comme celle-ci.

...ifelse : 'IF' condition 'THEN' dosomething+ 'ENDIF' 
...dosomething : assign | print | input; 

mais dosomething devient constante. Par exemple:

IF a > 3 THEN 
PRINT "HEllo" 
b = a 
ENDIF 

donc d'abord dosomething est print et la grammaire ne peut pas lire assing, input.

Si les déclarations deviennent comme ça, il fonctionne correctement

IF a > 3 THEN 
PRINT "HEllo" 
PRINT myName 
ENDIF 

donc je veux dire « ou » expression (| |)+ devient des constantes mêmes que la première expression survenue.

grammar hellog; 

prog : command+; 

command : maincommand 
     | expressioncommand 
     | flowcommand 
     ; 
//main 
maincommand : printcommand 
      | inputcommand 
      ; 

printcommand : 'PRINT' (IDINT | IDSTR | STRING) NL 
      | 'PRINT' (IDINT | IDSTR | STRING) (',' (IDINT | IDSTR | STRING))* NL 
      ; 
inputcommand : 'INPUT' (IDINT | IDSTR) NL 
      | 'INPUT' STRING? (IDINT | IDSTR) NL 
      ; 

//expression 
expressioncommand : intexpression 
        | strexpression 
        ; 
intexpression : IDINT '=' (IDINT | INT) NL 
       | IDINT '=' (IDINT | INT) (OPERATORMATH (IDINT | INT))* NL 
       ; 
strexpression : IDSTR '=' (IDSTR | STRING) NL 
       | IDSTR '=' (IDSTR | STRING) ('+' (IDSTR | STRING))* NL 
       ; 
//flow 
flowcommand : ifelseflow 
      | whileflow 
      ; 

ifelseflow : 'IF' conditionflow 'THEN' NL dosomething+ ('ELSEIF' conditionflow 'THEN' NL dosomething+)* ('ELSE' NL dosomething+)? 'ENDIF' NL; 
whileflow : 'WHILE' conditionflow NL (dosomething)+ 'WEND' NL; 
dosomething : command; 
conditionflow : (INT | IDINT) OPERATORBOOL (INT | IDINT) 
       | (STRING | IDSTR) '=' (STRING | IDSTR) 
       ; 

INT : [0-9]+; 
STRING : '"' .*? '"'; 
IDINT : [a-zA-Z]+; 
IDSTR : [a-zA-Z]+'$'; 
NL : '\n'; 
WS : [ \t\r]+ -> skip; 
OPERATORMATH : '+' | '-' | '*' | '/'; 
OPERATORBOOL : '=' | '>' | '<' | '>=' | '<='; 

J'ai juste besoin d'une grammaire pour exécuter ces expressions:

PRINT "Your name" 
INPUT name 
PRINT "HELLO" name 

a = 6 
IF a > 3 THEN 
PRINT a 
a = a -1 
END IF 

WHILE b = 3 
PRINT b 
a = b 
WEND 
+0

est '+' faux? (un ou plusieurs) – nooogii

+0

semble totalement ok, pourriez-vous s'il vous plaît montrer vos vraies règles de grammaire? – DAle

+0

@DAle bien sûr j'ai écrit ci-dessous – nooogii

Répondre

0

Ma réponse est pas exactement sur les | alternatives, mais s'il vous plaît continuez à lire, parce que, comme vous, je trouve la mise en œuvre de si. .else construit dans un langage de type BASIC un véritable challenge à implémenter. J'ai trouvé de bonnes ressources en ligne. Quand je l'ai eu raison, beaucoup, beaucoup de problèmes ont disparu tout à la fois et il vient de commencer à fonctionner. S'il vous plaît jeter un oeil à ma grammaire snip:

ifstmt 
: IF condition_block (ELSE IF condition_block)* (ELSE stmt_block)? 
; 

condition_block 
: expr stmt_block 
; 

stmt_block 
: OBRACE statement+ CBRACE 
| statement 
; 

Et ma mise en œuvre (dans le modèle de visiteur C#):

public override MuValue VisitIfstmt(LISBASICParser.IfstmtContext context) 
    { 
     LISBASICParser.Condition_blockContext[] conditions = context.condition_block(); 
     bool evaluatedBlock = false; 
     foreach (LISBASICParser.Condition_blockContext condition in conditions) 
     { 
      MuValue evaluated = Visit(condition.expr()); 
      if (evaluated.AsBoolean()) 
      { 
       evaluatedBlock = true; 
       Visit(condition.stmt_block()); 
       break; 
      } 
     } 
     if (!evaluatedBlock && context.stmt_block() != null) 
     { 
      Visit(context.stmt_block()); 
     } 
     return MuValue.Void; 
    } 

Une grande partie empruntée à une excellente mise en œuvre de son langage de démonstration Mu Bart Kiers. Beaucoup de bonnes idées dans ce projet de son. Il m'a vraiment montré la lumière et ce code que j'ai montré gère les déclarations if génial, imbriqué arbitrairement profond si vous en avez besoin. C'est un code de production exécutant un langage spécifique au domaine critique.