首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EBNF语法(ANTLR)

EBNF语法(ANTLR)
EN

Stack Overflow用户
提问于 2013-05-13 19:19:22
回答 1查看 1.8K关注 0票数 2

我在ANTLRWorks中遇到了一个关于EBNF语法的问题:

代码语言:javascript
复制
line 37:    
upper_lower_case
: LOWER_CASE 
| UPPER_CASE
;

line 42:
CLASSNAME 
:   UPPER_CASE (DIGITS | upper_lower_case )*
;

line 51:
UPPER_CASE 
:   'A'..'Z'
;

line 55:
LOWER_CASE 
:   'a'..'z'
;

line 60:
DIGITS  :   '0'..'9'
;

我希望CLASSNAME始终以大写字母开头,然后可以由数字、大写或小写字母组成。

错误日志:

代码语言:javascript
复制
[13:11:59] warning(200): classgenerator.g:43:42: 
Decision can match input such as "'0'..'9'" using multiple alternatives: 1, 2

As a result, alternative(s) 2 were disabled for that input
[13:11:59] warning(200): classgenerator.g:43:42: 
Decision can match input such as "<EOT>" using multiple alternatives: 2, 3

As a result, alternative(s) 3 were disabled for that input
[13:11:59] error(201): classgenerator.g:43:42: The following alternatives can never be 
matched: 3

[13:11:59] error(208): classgenerator.g:60:1: The following token definitions can never 
be matched because prior tokens match the same input: UPPER_CASE,DIGITS

有人能帮我解决这个问题吗?提前谢谢。

致敬,Hladeo

编辑:

那么,如果片段关键字不引用令牌,我应该使用它吗?这样使用fragment关键字会不会错呢?

代码语言:javascript
复制
tokens {
PUBLIC    = '+';
PRIVATE   = '-';
PROTECTED = '=';
}

fragment ACCESSOR
: PUBLIC
| PRIVATE
| PROTECTED
;

还有另一个问题。

代码语言:javascript
复制
OBJECTNAME  
:   UPPER_LOWER_CASE (UPPER_LOWER_CASE | DIGIT)*
;

OBJECTNAME应该至少包含一个字母(大写或小写都无关紧要),也可以由其他字母或数字组成--这部分代码有什么问题?当我尝试输入例如variable时-这是可以的,但是当我以大写字母Variable开头时,我得到一个错误:

代码语言:javascript
复制
line 1:15 mismatched input 'Variable' expecting OBJECTNAME
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-13 21:25:17

您的语法分析器规则CLASSNAME当前引用了语法分析器规则upper_lower_case (语法分析器规则以大写字母开头;语法分析器规则以小写字母开头)。词法分析器规则只能引用词法分析器规则。

此外,UPPER_CASELOWER_CASEDIGITS似乎不应自行创建令牌,因此应将它们标记为fragment规则。在下面的示例中,我将DIGITS更改为DIGIT,因为它只匹配一个数字。

代码语言:javascript
复制
CLASSNAME : UPPER_CASE (DIGIT | UPPER_LOWER_CASE)*;

fragment UPPER_LOWER_CASE : LOWER_CASE | UPPER_CASE;
fragment UPPER_CASE : 'A'..'Z';
fragment LOWER_CASE : 'a'..'z';
fragment DIGIT : '0'..'9';

编辑1(针对问题中的编辑):

  • 输入中的一段文本只能有一种标记类型。例如,考虑输入文本X3。由于此文本可以匹配CLASSNAMEOBJECTNAME,词法分析器将最终为其分配出现在语法中的第一个规则的类型。换句话说,如果在语法中CLASSNAME出现在OBJECTNAME之前,那么输入的X3将始终是CLASSNAME令牌,而永远不会是OBJECTNAME令牌。在语法中,如果OBJECTNAME出现在CLASSNAME之前,则输入的X3将始终是OBJECTNAME,而不是CLASSNAME (实际上,在这种情况下,任何令牌都不会是CLASSNAME).
  • Your ACCESSOR规则看起来应该是解析器规则,如下所示:

访问者: PUBLIC | PROTECTED | PRIVATE;

编辑2(有关区分CLASSNAME OBJECTNAME**):**和的注释

为了区分CLASSNAMEOBJECTNAME,您可以创建一个与之匹配的词法分析器规则IDENTIFIER

代码语言:javascript
复制
IDENTIFIER : UPPER_LOWER_CASE (DIGIT | UPPER_LOWER_CASE)*;

然后,您可以创建一个解析器规则来处理这种区别:

代码语言:javascript
复制
classname : IDENTIFIER;
objectname : IDENTIFIER;

显然,这允许x3成为classname,这在您的语言中是无效的。在可能的情况下,我总是倾向于稍微放宽解析器规则,稍后执行进一步的验证,以便提供更好的错误消息。例如,如果您允许x3匹配classname,那么在解析输入并具有AST (ANTLR3)或解析树(ANTLR4)之后,您可以查找classname的所有实例,并确保匹配的IDENTIFIER以所需的大写字母开头。

解析器的自动错误报告生成的错误消息示例:

行1:15不匹配的输入'variable‘应为CLASSNAME

单独验证产生的错误消息示例:

第1:15行类名variable必须以大写字母

开头

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16520805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档