4

我已经在这个问题上工作了大约 4 个小时。这是我的 ANTLR V4 语法文件,我已将其精简为最简单的示例。

grammar Cfscript;

component
    : (statement)*
    ;

statement
    : 'return' expression? ';'
    | statementExpression ';'
    ;

statementExpression
    : expression
    ;

expression
    : primary
    | expression '.' Identifier
    ;

primary
    : Identifier
    ;

Identifier
    : [a-zA-Z0-9_]+
    ;

WS
    : [ \t\r\n]+ -> skip 
    ;

我的文件包含

local.return;

当我尝试解析输入的此文件时,component我收到以下错误:mismatched input 'return' expecting Identifier. 我无法弄清楚为什么会发生此错误。

更新

如果我理解正确,这是因为return它是 Java 中的保留字,这就是他们以这种方式构建语法的原因。在我的语言中,Coldfusion Cfscriptreturn是有效的,只要它的范围是:local.return, variables.return, local["return"]. 这也适用于ifelsesavecontent许多其他词,所有这些词仅在范围内有效,但作为变量或表达式的第一项无效:if.blah = "something"无效,但blah.if = "something"有效。这意味着我会在每一个术语中遇到同样的问题,因为它们会与抓取它们的解析器规则相冲突。

综合 Bart 所说的,这是解决这个问题的一种干净的方法吗?

grammar Cfscript;

component
    : (statement)*
    ;

statement
    : K_Return expression? ';'
    | expression ';'
    ;

expression
    : primary
    | expression '.' secondary
    ;

primary
    : Identifier
    ;

secondary
    : K_Return
    | K_If
    | K_Else
    | Identifier
    ;

K_Return : 'return' ;
K_If : 'if' ;
K_Else : 'else' ;

Identifier
    : [a-zA-Z0-9_]+
    ;

WS
    : [ \t\r\n]+ -> skip 
    ;
4

1 回答 1

4

在解析器规则中添加文字标记,就像您对 所做的那样'return',并不意味着词法分析器会将字符串匹配"return"为规则Identifier中的第二个替代项expression

expression '.' Identifier

如果您想在您的语言中"return"作为关键字标识符进行匹配,则需要创建一个同时匹配Identifiers 和关键字的解析器规则:

expression
    : primary
    | expression '.' id
    ;

primary
    : id
    ;

id
    : Identifier
    | K_Return
    ;

// Better explicitly define them instead of litering keywords inside parser rules
K_Return
    : 'return'
    ;

Identifier
    : [a-zA-Z0-9_]+
    ;
于 2013-03-11T07:51:59.197 回答