鉴于gramar
grammar T;
options
{
k=4;
language=CSharp3;
TokenLabelType=CommonToken;
output=AST;
ASTLabelType=CommonTree;
}
tokens
{
LPAREN = '(';
RPAREN = ')';
LBRACK = '{';
RBRACK = '}';
}
fragment
ID : ('a'..'z'|'A'..'Z'|'_')('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
WS : (' ' | '\t' | '\n' |'\r' )+ { $channel = Hidden; } ;
public program: CLASSDEF+ EOF! ;
CLASSDEF: 'class' ID LBRACK
RBRACK ;
这会产生词法分析器和解析器,我使用如下
using System;
using Antlr.Runtime;
using Antlr.Runtime.Tree;
namespace compiler
{
internal class Program2
{
public static void Main(string[]arg)
{
ANTLRStringStream Input = new ANTLRStringStream(@"class foo
{
}");
TLexer lex = new TLexer(Input);
Console.WriteLine("errors:" + lex.NumberOfSyntaxErrors);
CommonTokenStream tokens = new CommonTokenStream(lex);
TParser parser = new TParser(tokens);
var parsed = parser.program();
Console.WriteLine("errors: " + parser.NumberOfSyntaxErrors);
CommonTree tree = parsed.Tree;
Console.WriteLine("type:" + tree.Type);
Console.WriteLine("text:" + tree.Text);
Console.WriteLine("children:" +tree.ChildCount);
Console.WriteLine(tree.ToString());
Console.WriteLine(tree.ToStringTree());
Console.ReadKey();
}
}
}
运行此代码时,我得到0个lex错误和1个解析错误
结果
errors:0
errors: 1
type:0
text:{
}
children:0
<error: {
}>
<error: {
}>
问题!
我认为ANTLR应该提供智能错误信息,但我没有发现什么错误
我是否遗漏了改进错误消息的代码?
答案 0 :(得分:3)
您使CLASSDEF
成为词法规则(换句话说:单个令牌),这是不正确的。当词法分析器偶然发现"class X"
之类的输入时,它无法创建CLASSDEF
令牌,因为"class"
和"X"
之间存在空格(并且不会WS
令牌由于CLASSDEF
是词法分析器规则,因此无法帮助您。
换句话说:改为使CLASSDEF
成为解析器规则(并从fragment
移除ID
!):
grammar T;
options
{
language=CSharp3;
output=AST;
}
tokens
{
CLASS = 'class';
LPAREN = '(';
RPAREN = ')';
LBRACK = '{';
RBRACK = '}';
}
public program
: class_def+ EOF!
;
class_def
: CLASS ID LBRACK RBRACK
;
ID
: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
WS
: (' ' | '\t' | '\n' |'\r' )+ { $channel = Hidden; }
;
现在解析像"class foo { }"
这样的输入将产生以下解析: