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;
}