为什么 antlr 规则不会生成一个好的解析树?

Why whould antlr rule won't making a nice parse tree?

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

[你好:/c=0.3//a=hi/][什么:/c=0.4/][是:/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),其余都是标记,这是解析树:

      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     : '.';

这将为您的输入创建以下解析树: