Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# “网络中的antlr4”;输入不匹配';开始';期待{';';';+;';';';';';';&#,国防部}_C#_Compiler Construction_Antlr4 - Fatal编程技术网

C# “网络中的antlr4”;输入不匹配';开始';期待{';';';+;';';';';';';&#,国防部}

C# “网络中的antlr4”;输入不匹配';开始';期待{';';';+;';';';';';';&#,国防部},c#,compiler-construction,antlr4,C#,Compiler Construction,Antlr4,我在C#中使用了antlr4 一切都很好,除了当我使用“阻塞”时,一切都变得疯狂 例如,这是我的输入代码: a:int; a:=2; if(a==2) begin a:= a * 2; a:=a + 5; end 这是我的语法: grammar Our; options{ language=CSharp; TokenLabelType=CommonToken; ASTLabelType=CommonTree; } statements : statement

我在C#中使用了antlr4

一切都很好,除了当我使用“阻塞”时,一切都变得疯狂

例如,这是我的输入代码:

a:int;
a:=2;
if(a==2) begin
a:= a * 2;
a:=a + 5;
end
这是我的语法:

grammar Our;

options{
    language=CSharp;
    TokenLabelType=CommonToken;
    ASTLabelType=CommonTree;
}

statements  :   statement statements
        |EOF;
statement   :
            expression SEMI
        |   ifstmt
        |   whilestmt 
        |   forstmt
        |   readstmt SEMI
        |   writestmt SEMI
        |   vardef SEMI
        |   block
        ;

block       :   BEGIN statements END ;

expression  :   ID ASSIGN expression
        |   boolexp;

boolexp     :   relexp AND boolexp
        |   relexp OR boolexp
        |   relexp;

relexp      :   modexp EQUAL relexp
        |   modexp LE relexp 
        |   modexp GE relexp
        |   modexp NOTEQUAL relexp 
        |   modexp GT relexp 
        |   modexp LT relexp
        |   modexp;

modexp      :   modexp  MOD exp 
        //| exp DIV modexp 
        |   exp;

exp         :   exp  ADD term 
        |   exp  SUB  term 
        |   term;

term        :   term MUL factor 
        |   term DIV factor
        |   factor POW term 
        |   factor;

factor      :   LPAREN expression RPAREN
        |   LPAREN vartype RPAREN  factor
        |   ID
        |   SUB factor
        |   ID LPAREN explist RPAREN 
        |   ID LPAREN RPAREN
        |   ID LPAREN LPAREN NUM RPAREN RPAREN 
        |   ID LPAREN LPAREN NUM COMMA NUM RPAREN RPAREN
        |   const;

explist     :   exp  COMMA  explist
        |exp;

const       :   NUM 
        |   BooleanLiteral          
        |   STRING;

ifstmt      :   IF LPAREN boolexp RPAREN statement
        |   IF LPAREN boolexp  RPAREN statement ELSE statement ;

whilestmt   :   WHILE LPAREN boolexp  RPAREN statement ;

forstmt     :   FOR ID ASSIGN exp  COLON exp statement;

readstmt    :   READ LPAREN  idlist  RPAREN ;

idlist      :   ID COMMA idlist
        |ID;

writestmt   :   WRITE  LPAREN explist RPAREN ;

vardef      :   idlist COLON vartype;


vartype     :   basictypes 
        |   basictypes LPAREN NUM RPAREN 
        |   basictypes LPAREN NUM COMMA NUM RPAREN ;

basictypes  :   INT 
        |   FLOAT 
        |   CHAR 
        |   STRING 
        |   BOOLEAN  ; 


BEGIN         : 'begin';
END           : 'end';
To            : 'to';
NEXT          : 'next';
REAL          : 'real';
BOOLEAN       : 'boolean';
CHAR          : 'char';
DO            : 'do';
DOUBLE        : 'double';
ELSE          : 'else';
FLOAT         : 'float';
FOR           : 'for';
FOREACH       : 'foreach';
FUNCTION      : 'function';
IF            : 'if';
INT           : 'int';
READ          : 'read';
RETURN        : 'return';
VOID          : 'void';
WHILE         : 'while';
WEND          : 'wend';
WRITE         : 'write';

LPAREN          : '(';
RPAREN          : ')';
LBRACE          : '{';
RBRACE          : '}';
LBRACK          : '[';
RBRACK          : ']';
SEMI            : ';';
COMMA           : ',';

ASSIGN          : ':=';
GT              : '>';
LT              : '<';
COLON           : ':';
EQUAL           : '==';
LE              : '<=';
GE              : '>=';
NOTEQUAL        : '!=';
AND             : '&&'|'and';
OR              : '||'|'or';
INC             : '++';
DEC             : '--';
ADD             : '+';
SUB             : '-';
MUL             : '*';
DIV             : '/'|'div';
MOD             : '%'|'mod';
ADD_ASSIGN      : '+=';
SUB_ASSIGN      : '-=';
MUL_ASSIGN      : '*=';
DIV_ASSIGN      : '/=';
POW             : '^';

BooleanLiteral : 'true'|'false';

STRING : '\"'([a-zA-Z]|NUM)*'\"';

ID : ([a-z]|[A-Z])([a-z]|[A-z]|[0-9])*;

NUM : ('+'|'-')?[0-9]([0-9]*)('.'[0-9][0-9]*)?;

WS  :  [ \t\r\n\u000C]+ -> skip ;

COMMENT : '/*' .*? '*/' ;

LINE_COMMENT : '//' ~[\r\n]*;
我们的语法;
选择权{
语言=CSharp;
TokenLabelType=CommonToken;
ASTLabelType=CommonTree;
}
声明:声明声明
|EOF;
声明:
半表达式
|ifstmt
|whilesmt
|福斯特
|readstmt-SEMI
|writestmt-SEMI
|vardef SEMI
|挡块
;
块:开始语句结束;
表达式:ID分配表达式
|boolexp;
boolexp:relexp和boolexp
|relexp或boolexp
|relexp;
relexp:modexp等于relexp
|可释放模式
|modexp GE relexp
|modexp NOTEQUAL relexp
|modexp GT relexp
|modexp LT relexp
|modexp;
modexp:modexp MOD exp
//|exp DIV modexp
|经验;
exp:exp添加术语
|exp子项
|术语;
术语:术语多因子
|术语分割因子
|因子功率项
|因素;
因子:LPAREN表达式RPAREN
|LPAREN vartype RPAREN因子
|身份证
|子因素
|ID LPAREN解释程序RPAREN
|ID LPAREN RPAREN
|ID LPAREN LPAREN NUM RPAREN RPAREN
|ID LPAREN LPAREN NUM逗号NUM RPAREN RPAREN
|常数;
explist:exp逗号explist
|经验;
常数:NUM
|布尔文字
|弦;
ifstmt:IF LPAREN boolexp RPAREN语句
|IF LPAREN boolexp RPAREN语句ELSE语句;
whilesmt:whilelparen boolexp RPAREN语句;
forstmt:FOR ID ASSIGN exp COLON exp语句;
readstmt:读取LPAREN idlist rpare;
idlist:ID逗号idlist
|身份证;
writestmt:编写LPAREN解释程序RPAREN;
vardef:idlist冒号vartype;
vartype:基本类型
|基本类型LPAREN NUM RPAREN
|基本类型LPAREN NUM COMMA NUM RPAREN;
基本类型:INT
|浮动
|煤焦
|串
|布尔型;
开始:“开始”;
结束:"结束";;
至:‘至’;
下一个:“下一个”;
真实:“真实”;
布尔:'布尔';
CHAR:‘CHAR’;
DO:‘DO’;
双:‘双’;
ELSE:‘ELSE’;
浮动:“浮动”;
因为‘为了’;
FOREACH:‘FOREACH’;
功能:‘功能’;
如果:‘如果’;
INT:‘INT’;
读:“读”;
RETURN:‘RETURN’;
无效:“无效”;
WHILE:‘WHILE’;
温德:“温德”;
写:‘写’;
LPAREN:'(';
RPAREN:')';
LBRACE:“{”;
RBRACE:'}';
LBRACK:'[';
RBRACK:']';
半:';';
逗号:',';
分配:':=';
GT:“>”;

LT:“问题在于您的语句列表规则:

statements : statement statements | EOF ;
此规则有两个选项:一个
语句,后跟另一个
语句列表,或者
EOF
。唯一的非递归选项是
EOF
,当您在
块的规则中使用此选项时,这将成为一个问题:

block : BEGIN statements END ;
>在<代码> Bux<代码>的中间,你永远不能遇到<代码> EOF<代码>,所以当解析器在你的示例输入中读取Eng/<代码>之前的行时,它期望读取的下一个东西是另一个<代码>语句< /代码>。单词
end
本身不是有效的
语句
,这就是它抛出您看到的错误的原因

一种可能的修复方法是将
语句的递归部分设置为可选:

statements : statement statements? | EOF ;
这将允许您的示例输入成功解析。在我看来,更好的选择是完全删除递归:

statements : statement* | EOF ;
最后,您可以看到,
EOF
仍然是
语句
规则的选项之一。当您在<代码> Bux<代码>的规则中使用此规则时,这是没有多大意义的,因为您不应该在<代码>块中间找到<代码> EOF <代码>。我要做的是将其移动到一个新的顶级解析器规则:

program : statements EOF ;
statements : statement* ;