Parsing ANTLR';或';正则表达式

Parsing ANTLR';或';正则表达式,parsing,antlr,grammar,Parsing,Antlr,Grammar,我对|表达式有一个严重的问题 我的语法包含这样的表达 ...ifelse : 'IF' condition 'THEN' dosomething+ 'ENDIF' ...dosomething : assign | print | input; 但是dosomething变为常量。例如: IF a > 3 THEN PRINT "HEllo" b = a ENDIF 所以首先dosomething是print,语法不能阅读assing,input 如果语句变成这样,它就正确了 IF a

我对
|
表达式有一个严重的问题

我的语法包含这样的表达

...ifelse : 'IF' condition 'THEN' dosomething+ 'ENDIF'
...dosomething : assign | print | input;
但是
dosomething
变为常量。例如:

IF a > 3 THEN
PRINT "HEllo"
b = a
ENDIF
所以首先
dosomething
print
,语法不能阅读
assing,input

如果语句变成这样,它就正确了

IF a > 3 THEN
PRINT "HEllo"
PRINT myName
ENDIF
所以我的意思是“或”
(| |)+
表达式变成常量,与第一个出现的表达式相同

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 : '=' | '>' | '<' | '>=' | '<=';

我的答案并不完全是关于
|
备选方案,但请继续阅读,因为和您一样,我发现在类似BASIC的语言中实现if..else构造是一个真正的挑战。我在网上找到了一些很好的资源。当我做对的时候,很多很多问题一下子就消失了,它才开始工作。请看一下我的语法剪报:

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

condition_block
:   expr stmt_block
;

stmt_block
:   OBRACE statement+ CBRACE
|   statement
;
以及我的实现(在C#visitor模式中):


大量借鉴了Bart Kiers对其Mu演示语言的出色实现。他的那个项目有很多好主意。它向我展示了光明,我展示的这段代码处理了
if
语句,非常好,如果需要,可以任意嵌套。这是运行关键领域特定语言的生产代码。

是否“+”错误?(一个或多个)看起来完全没问题,你能展示一下你真正的语法规则吗?@DAle当然,我在下面写道Hanks!(但要正确地执行此操作,您需要将其包含在问题中,而不是添加为答案)。对于
打印“HEllo”
b=a
示例,您有什么错误消息?
ifstmt
:   IF condition_block (ELSE IF condition_block)* (ELSE stmt_block)?
;

condition_block
:   expr stmt_block
;

stmt_block
:   OBRACE statement+ CBRACE
|   statement
;
 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;
    }