Antlr4 为什么antlr规则获胜';做一个好的解析树?
我正在尝试创建一个语法来帮助我解析如下字符串: [你好:/c=0.3//a=hi/][what:/c=0.4/][are:/c=0.6//a=is/] 这是我的语法: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
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)和文本。