ANTLR:Lexer无法识别令牌

ANTLR:Lexer无法识别令牌,antlr,antlr3,lexer,parser-generator,Antlr,Antlr3,Lexer,Parser Generator,给定以下Lexer语法: lexer grammar CodeTableLexer; CodeTabHeader : '[code table 1.0]'; Code : 'code'; Table : 'table'; End : 'end'; Row : 'row'; Naming : 'naming'; Dfltlang : 'dfltlang'; Languag

给定以下Lexer语法:

lexer grammar CodeTableLexer;

CodeTabHeader   : '[code table 1.0]';
Code            : 'code';
Table           : 'table';
End             : 'end';
Row             : 'row';
Naming          : 'naming';
Dfltlang        : 'dfltlang';
Language        : 'english' | 'german' | 'french' | 'italian' | 'spanish';
Null            : 'null';

Number
    : Int ('.' Digit*)?
    ;

Identifier
    : ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '$' | '.' | Digit)*
    ;

String
@after {
    setText(getText().substring(1, getText().length() - 1).replaceAll("\\\\(.)", "$1"));
}
    : '"' (~('"'))* '"'
    ;

Comment
    : '--' ~('\r' | '\n')* { skip(); }
    | '/*' .* '*/'         { skip(); }
    ;

Space
    : (' ' | '\t' | '\r' | '\n' | '\u000C') { skip(); }
    ;

fragment Int
    : '1'..'9'
    | '0'
    ;

fragment Digit
    : '0'..'9'
    ;
parser grammar CodeTableParser;

parse
    : header^ begin (row)* end EOF
    ;

header
    : CodeTabHeader
    ;

begin
    : Code Table Identifier row
    ;

row
    : Row (Number | Identifier) value
    ;

value
    : (Identifier (Number | Identifier | String))+
        (Naming Dfltlang String (Language String)*)?
    ;

end
    : End Code Table
    ;
。。。以下语法分析器:

lexer grammar CodeTableLexer;

CodeTabHeader   : '[code table 1.0]';
Code            : 'code';
Table           : 'table';
End             : 'end';
Row             : 'row';
Naming          : 'naming';
Dfltlang        : 'dfltlang';
Language        : 'english' | 'german' | 'french' | 'italian' | 'spanish';
Null            : 'null';

Number
    : Int ('.' Digit*)?
    ;

Identifier
    : ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '$' | '.' | Digit)*
    ;

String
@after {
    setText(getText().substring(1, getText().length() - 1).replaceAll("\\\\(.)", "$1"));
}
    : '"' (~('"'))* '"'
    ;

Comment
    : '--' ~('\r' | '\n')* { skip(); }
    | '/*' .* '*/'         { skip(); }
    ;

Space
    : (' ' | '\t' | '\r' | '\n' | '\u000C') { skip(); }
    ;

fragment Int
    : '1'..'9'
    | '0'
    ;

fragment Digit
    : '0'..'9'
    ;
parser grammar CodeTableParser;

parse
    : header^ begin (row)* end EOF
    ;

header
    : CodeTabHeader
    ;

begin
    : Code Table Identifier row
    ;

row
    : Row (Number | Identifier) value
    ;

value
    : (Identifier (Number | Identifier | String))+
        (Naming Dfltlang String (Language String)*)?
    ;

end
    : End Code Table
    ;
。。。最后是要分析的以下源代码:

[code table 1.0]

code table my_table
row 1
    id              "my_id_1"
    name            "my_name_1"
    descn           "my_description_1"
    naming
        dfltlang    "My description 1"
        english     "My description 1"
        german      "Meine Beschreibung 1"

row 2
    id              "my_id_2"
    name            "my_name_2"
    descn           "my_description_2"
    naming
        dfltlang    "My description 2"
        english     "My description 2"
        german      "Meine Beschreibung 2"

end code table
我总是收到错误信息

line 1:0 extraneous input '[code table 1.0]' expecting CodeTabHeader
我有点困惑…token CodeTabHeader在我的lexer中定义为“[code table 1.0]”;我错过什么了吗?任何帮助都将不胜感激

谢谢,
J3d

如果将lexer和解析器拆分为两个不同的文件,请在解析器的
选项
-块中明确指出它应该使用哪些标记:

options {
  tokenVocab=CodeTableLexer;
}

如果将lexer和parser拆分为两个不同的文件,请在解析器的
选项
-块中明确指出应使用哪些标记:

options {
  tokenVocab=CodeTableLexer;
}

尝试更改CodeTabHeader:“[code table 1.0]”;在CodeTabHeader上:'[代码表1.0]\n'@卡莫巴普,不,不可能<代码>\n被lexer丢弃。请尝试更改CodeTabHeader:“[code table 1.0]”;在CodeTabHeader上:'[代码表1.0]\n'@卡莫巴普,不,不可能<代码>\n已被lexer丢弃。抱歉。。。但是缺少的“表格”只是一个打字错误(我刚刚在我的帖子中修复了它)。无论如何,原始语法文件是正确的。您得到的错误是因为代码表名为“my_table”,其中包含单词“table”(在我的示例中,这是另一个问题:如果标识符包含保留字,则解析器会投诉)。如果您将其重命名为“mystuff”,您将得到与我完全相同的错误消息。找到。。。如果我将lexer和parser放在同一个文件中,那么一切都可以正常工作;只要我使用两个单独的文件(CodeTableLexer.g和CodeTableParser.g),我就会得到我在帖子中提到的错误。在使用单独的文件(一个用于lexer,另一个用于解析器)时,有什么我应该注意的吗?非常感谢!我也读了你的教程。。。伟大的工作-我认为这是最好的教程。再次感谢。是否有任何方法可以遍历生成的StringTemplate?我需要做的是解析同一源代码的两个不同版本,并重新安排它们,以便公共部分先出现,其余部分在最后。我在你的教程中看到了walker的例子。。。但我想知道是否有一种更简单的方法来操作内存中的源代码。[我想做的是一个旨在促进合并活动的工具]。@j3d,对不起,没有听到你的评论。我对StringTemplate没有太多经验:最好创建一个单独的问题,并用
antlr
StringTemplate
标记它。祝你好运很抱歉但是缺少的“表格”只是一个打字错误(我刚刚在我的帖子中修复了它)。无论如何,原始语法文件是正确的。您得到的错误是因为代码表名为“my_table”,其中包含单词“table”(在我的示例中,这是另一个问题:如果标识符包含保留字,则解析器会投诉)。如果您将其重命名为“mystuff”,您将得到与我完全相同的错误消息。找到。。。如果我将lexer和parser放在同一个文件中,那么一切都可以正常工作;只要我使用两个单独的文件(CodeTableLexer.g和CodeTableParser.g),我就会得到我在帖子中提到的错误。在使用单独的文件(一个用于lexer,另一个用于解析器)时,有什么我应该注意的吗?非常感谢!我也读了你的教程。。。伟大的工作-我认为这是最好的教程。再次感谢。是否有任何方法可以遍历生成的StringTemplate?我需要做的是解析同一源代码的两个不同版本,并重新安排它们,以便公共部分先出现,其余部分在最后。我在你的教程中看到了walker的例子。。。但我想知道是否有一种更简单的方法来操作内存中的源代码。[我想做的是一个旨在促进合并活动的工具]。@j3d,对不起,没有听到你的评论。我对StringTemplate没有太多经验:最好创建一个单独的问题,并用
antlr
StringTemplate
标记它。祝你好运