如何用树语法中的文本重写令牌?

时间:2011-05-30 21:22:04

标签: java antlr antlr3

这是我的树语法:

grammar t;
options{
  output = AST;
}
type
  :
  'NVARCHAR' -> "VARCHAR"
  ;

ANTLR3 3.1.3说:

syntax error: antlr: t.g:12:5: unexpected token: 'NVARCHAR'

这里有什么问题?我是从this article获得的。

PS。我之前使用这个语法是为了让AST退出它。一旦检索到AST,我就会遍历它并将每个令牌的文本添加到某个字符串缓冲区。上面重写的想法是替换某些令牌。我正在进行语言到语言的映射(SQL到SQL方言,更具体一点)。

2 个答案:

答案 0 :(得分:4)

请注意Terence开头的第一句话:“只是对语义规则规范语言有一些很酷的想法......”。这就是第一个例子:一个想法。这不是有效的语法。

您有(至少)两种选择:


1。立即重写令牌中的文本

grammar T;

options{
  output=AST;
}

@parser::members {
  public static void main(String[] args) throws Exception {
    TLexer lexer = new TLexer(new ANTLRStringStream("NVARCHAR"));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    parser.type();
  }
}

type
  :  NVARCHAR {System.out.println("token=" + $NVARCHAR.text);}
  ;

NVARCHAR
  :  'NVARCHAR' {setText("VARCHAR");}
  ;

但这只会调整text,而不会调整令牌的type,这仍然是NVARCHAR类型。


2。使用虚构的令牌:

grammar T;

options{
  output=AST;
}

tokens {
  VARCHAR='VARCHAR';
}

@parser::members {
  public static void main(String[] args) throws Exception {
    TLexer lexer = new TLexer(new ANTLRStringStream("NVARCHAR"));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    parser.type();
  }
}

type
  :  NVARCHAR -> VARCHAR
  ;

NVARCHAR
  :  'NVARCHAR'
  ;

更改了令牌的text type


如您所见,通过这两个演示,token=VARCHAR正在打印到控制台:

bart@hades:~/Programming/ANTLR/Demos/T$ java -cp antlr-3.3.jar org.antlr.Tool T.g
bart@hades:~/Programming/ANTLR/Demos/T$ javac -cp antlr-3.3.jar *.java
bart@hades:~/Programming/ANTLR/Demos/T$ java -cp .:antlr-3.3.jar TParser 
token=VARCHAR

答案 1 :(得分:1)

在antlr4中替换文本和类型的

可以通过type动作实现:

OldTokenType: 
    ('Token1' | 'Token2' | 'Token3' ) {setText("New Token");} 
    -> type(NewTokenType);