C# 中的 ANTLR4 仅捕获一个标记
ANTLR4 in C# catches only one token
g4 文件:
grammar TestFlow;
options
{
language=CSharp4;
output=AST;
}
/*
* Parser Rules
*/
compileUnit : LC | BC ;
/*
* Lexer Rules
*/
BC : '/*' .*? '*/' ;
LC : '//' .*? [\r\n] ;
代码:
var input = " /*aaa*/ /// \n ";
var stream = new AntlrInputStream(input);
ITokenSource lexer = new TestFlowLexer(stream);
ITokenStream tokens = new CommonTokenStream(lexer);
var parser = new TestFlowParser(tokens);
parser.BuildParseTree = true;
var tree = parser.compileUnit();
var n = tree.ChildCount;
var top = new List<string>();
for (int i = 0; i < n; i++) {
top.Add(tree.GetChild(i).GetText());
}
在 运行 上面的代码之后,我在 top
中得到了单个字符串:/*aaa*/
。单行注释没有被捕获。
怎么了?
所有 parser/lexer 生成错误和警告都很重要。这两个 options
语句在当前版本的 Antlr4 中都是无效的。
运行时错误详细说明了根本问题:无法识别的输入字符,具体来说,语法不处理空格。添加一个词法分析器规则来修复:
WS: [ \r\n\t] -> skip ;
虽然不一定是问题,但要求解析器处理所有输入是一种很好的形式。词法分析器将在源输入的末尾生成一个 EOF
标记。修复主要规则以要求 EOF
:
compileUnit : ( LC | BC ) EOF ;
允许重复的正确方法是使用 *
或 +
运算符:
compileUnit : ( LC | BC )+ EOF ;
g4 文件:
grammar TestFlow;
options
{
language=CSharp4;
output=AST;
}
/*
* Parser Rules
*/
compileUnit : LC | BC ;
/*
* Lexer Rules
*/
BC : '/*' .*? '*/' ;
LC : '//' .*? [\r\n] ;
代码:
var input = " /*aaa*/ /// \n ";
var stream = new AntlrInputStream(input);
ITokenSource lexer = new TestFlowLexer(stream);
ITokenStream tokens = new CommonTokenStream(lexer);
var parser = new TestFlowParser(tokens);
parser.BuildParseTree = true;
var tree = parser.compileUnit();
var n = tree.ChildCount;
var top = new List<string>();
for (int i = 0; i < n; i++) {
top.Add(tree.GetChild(i).GetText());
}
在 运行 上面的代码之后,我在 top
中得到了单个字符串:/*aaa*/
。单行注释没有被捕获。
怎么了?
所有 parser/lexer 生成错误和警告都很重要。这两个 options
语句在当前版本的 Antlr4 中都是无效的。
运行时错误详细说明了根本问题:无法识别的输入字符,具体来说,语法不处理空格。添加一个词法分析器规则来修复:
WS: [ \r\n\t] -> skip ;
虽然不一定是问题,但要求解析器处理所有输入是一种很好的形式。词法分析器将在源输入的末尾生成一个 EOF
标记。修复主要规则以要求 EOF
:
compileUnit : ( LC | BC ) EOF ;
允许重复的正确方法是使用 *
或 +
运算符:
compileUnit : ( LC | BC )+ EOF ;