Antlr4 为什么antlr规则获胜';做一个好的解析树?

Antlr4 为什么antlr规则获胜';做一个好的解析树?,antlr4,Antlr4,我正在尝试创建一个语法来帮助我解析如下字符串: [你好:/c=0.3//a=hi/][what:/c=0.4/][are:/c=0.6//a=is/] 这是我的语法: grammar MyGrammar; WS: [ \t\r\n]+ -> skip; // skip spaces, tabs, newlines sentence: WORD+; WORD: '[' WORD_DESCRIPTOR ']'; WORD_DESCRIPTOR: WORD_IDENTIFIER ':' W

我正在尝试创建一个语法来帮助我解析如下字符串:

[你好:/c=0.3//a=hi/][what:/c=0.4/][are:/c=0.6//a=is/]

这是我的语法:

grammar MyGrammar;
WS: [ \t\r\n]+ -> skip; // skip spaces, tabs, newlines

sentence: WORD+;

WORD: '[' WORD_DESCRIPTOR ']';

WORD_DESCRIPTOR: WORD_IDENTIFIER ':' WORD_FEATURES_DESCRIPTORS;

WORD_IDENTIFIER: STRING;

WORD_FEATURES_DESCRIPTORS: WORD_FEATURE_DESCRIPTOR+;

WORD_FEATURE_DESCRIPTOR: '/' WORD_FEATURE_IDENTIFIER '=' WORD_FEATURE_VALUE '/';

WORD_FEATURE_IDENTIFIER:
    C_FEATURE | A_FEATURE
    ;

C_FEATURE: 'c';
A_FEATURE: 'a';

WORD_FEATURE_VALUE: STRING | NUMBER;

fragment LETTER : LOWER | UPPER ;
fragment LOWER  : 'a'..'z' ;
fragment UPPER  : 'A'..'Z' ;
fragment DIGIT  : '0'..'9' ;
fragment INTEGER: DIGIT+ ;
fragment NUMBER: INTEGER (DOT INTEGER)? ;
fragment STRING: LETTER+ ;
fragment DOT: '.' ;
问题是解析树只有一个级别。
我做错了什么?

您的解析树显示它的方式,因为所有标记都是叶节点,所有解析器规则都是内部节点。由于您只有一个解析器规则(
语句
),其余都是令牌,因此这是解析树:

      sentence
     / |    | \
    /  |    |  \
WORD WORD WORD WORD ...
您应该将标记视为构建语言的原子。一旦您开始创建令牌,比如
TOKEN:TOKEN|A | TOKEN|B,那么这通常更好地定义为解析器规则:
token:token|a | token|B

请尝试以下方法:

sentence                 : word+ EOF;
word                     : '[' word_descriptor ']';
word_descriptor          : word_identifier ':' word_feature_descriptors;
word_identifier          : STRING;
word_feature_descriptors : word_feature_descriptor+;
word_feature_descriptor  : '/' word_feature_identifier '=' word_feature_value '/';
word_feature_value       : STRING | NUMBER;
word_feature_identifier  : C_FEATURE | A_FEATURE;

C_FEATURE : 'c';
A_FEATURE : 'a';
NUMBER    : INTEGER (DOT INTEGER)?;
STRING    : LETTER+ ;
WS        : [ \t\r\n]+ -> skip; // skip spaces, tabs, newlines

fragment LETTER  : LOWER | UPPER;
fragment LOWER   : [a-z];
fragment UPPER   : [A-Z];
fragment DIGIT   : [0-9];
fragment INTEGER : DIGIT+;
fragment DOT     : '.';
这将为您的输入创建以下解析树:


解析树的显示方式与之相同,因为所有标记都是叶节点,而所有解析器规则都是内部节点。由于您只有一个解析器规则(
语句
),其余都是令牌,因此这是解析树:

      sentence
     / |    | \
    /  |    |  \
WORD WORD WORD WORD ...
您应该将标记视为构建语言的原子。一旦您开始创建令牌,比如
TOKEN:TOKEN|A | TOKEN|B,那么这通常更好地定义为解析器规则:
token:token|a | token|B

请尝试以下方法:

sentence                 : word+ EOF;
word                     : '[' word_descriptor ']';
word_descriptor          : word_identifier ':' word_feature_descriptors;
word_identifier          : STRING;
word_feature_descriptors : word_feature_descriptor+;
word_feature_descriptor  : '/' word_feature_identifier '=' word_feature_value '/';
word_feature_value       : STRING | NUMBER;
word_feature_identifier  : C_FEATURE | A_FEATURE;

C_FEATURE : 'c';
A_FEATURE : 'a';
NUMBER    : INTEGER (DOT INTEGER)?;
STRING    : LETTER+ ;
WS        : [ \t\r\n]+ -> skip; // skip spaces, tabs, newlines

fragment LETTER  : LOWER | UPPER;
fragment LOWER   : [a-z];
fragment UPPER   : [A-Z];
fragment DIGIT   : [0-9];
fragment INTEGER : DIGIT+;
fragment DOT     : '.';
这将为您的输入创建以下解析树:


解析树是扁平的,因为这是您指定的--“句子:WORD+;”,因此,解析树将是“句子”的一个根节点,而子节点是每个“单词”树的叶子。lexer生成不具有树结构的令牌。标记基本上有标记类型(int)和文本。解析树是扁平的,因为这是您指定的--“句子:WORD+;”,因此,解析树将是“句子”的一个根节点和每个“单词”树的叶子。lexer生成不具有树结构的令牌。令牌基本上有令牌类型(int)和文本。