1

鉴于语法

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: {
}>

问题!

  1. 我认为 ANTLR 应该提供智能错误消息,但我没有找出问题所在

  2. 我是否缺少改进错误消息的代码?

4

1 回答 1

3

您制定CLASSDEF了一个词法分析器规则(换句话说:单个标记),这是不正确的。当词法分析器偶然发现输入 like"class X"时,它​​无法创建标记,因为andCLASSDEF之间有一个空格(不,标记不会帮助您,因为这是词法分析器规则)。"class""X"WSCLASSDEF

换句话说:改为制定解析器规则(并从中CLASSDEF删除!):fragmentID

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 { }"将产生以下解析:

在此处输入图像描述

于 2012-08-05T19:58:56.220 回答