0

这个问题埋在另一个问题的更新部分,现在专门问它。

我正在使用antlr3.4。

我有一个简单的语法试图解析两种类型的文本,该行以“#include”和其他开头。这是我的语法:

cmds
    : cmd+
    ;

cmd
    : include_cmd |  other_cmd
    ;

include_cmd
    : INCLUDE  DOUBLE_QUOTE  FILE_NAME  DOUBLE_QUOTE
    ;

other_cmd
    : (~INCLUDE)+
    ;


INCLUDE
    : '#include'
    ;

DOUBLE_QUOTE
    : '"'
    ;

FILE_NAME
    : ('a'..'z' | 'A'..'Z' | '0'..'9' | '_')+
    ;

New_Line 
    : ('\r' | '\n')+   
    ;

WS 
    : ('\t' | ' ')+  {$channel = HIDDEN;}
    ;

但我收到这样的警告:

Decision can match input such as "{DOUBLE_QUOTE..FILE_NAME, New_Line..WS}" using multiple alternatives: 1, 2

As a result, alternative(s) 2 were disabled for that input

我想这是因为双引号可以同时匹配 other_cmd 规则和 DOUBLE_QUOTE 规则,但我想知道,一个是解析器规则,另一个是词法分析器规则,这个警告有意义吗?

任何帮助清除此警告?

一个附带问题 - 警告消息只是说替代 1,2,但我并不清楚什么是 1,什么是 2,有没有办法让 antlr 提供更直接的替代方案?

4

1 回答 1

1

我猜这是因为双引号可以同时匹配 other_cmd 规则和 DOUBLE_QUOTE 规则,...

不,这不是问题,因为从无法匹配include_cmd的东西开始。other_cmd

决策可以使用多种选择匹配输入,例如“{DOUBLE_QUOTE..FILE_NAME, New_Line..WS}”:1、2

警告意味着解析器可以通过多种方式匹配输入foo"(aFILE_NAME后跟 a ):DOUBLE_QUOTE

1.贪婪

在此处输入图像描述

2.不贪心

在此处输入图像描述

ANTLR 将选择贪婪解析,但由于可能存在不贪婪,因此会生成警告。如果您明确告诉解析器贪婪匹配,则不会再发出警告:

other_cmd
 : (options {greedy=true;} : ~INCLUDE)+
 ;

一个附带问题 - 警告消息只是说替代 1,2,但我并不清楚什么是 1,什么是 2,有没有办法让 antlr 提供更直接的替代方案?

不,据我所知没有。这个警告确实相当神秘。替代项通常表示解析器可以遵循的分支:

parser_rule
 : alternative_1 
 | alternative_2
 | alternative_3
 ;

但是在您的情况下,似乎 ANTLR 正在谈论令牌范围是替代方案:DOUBLE_QUOTE..FILE_NAME成为替代方案并New_Line..WS成为第二个。

于 2013-02-02T11:55:19.217 回答