这是我要解析的代码示例。当我覆盖ANTLR创建的parserBaseListener.java文件中的函数时,我想要getSaveable PaymentMethodsSmartList()
作为标记。
/** @suppress */
public any function getSaveablePaymentMethodsSmartList() {
if(!structKeyExists(variables, "saveablePaymentMethodsSmartList")) {
variables.saveablePaymentMethodsSmartList = getService("paymentService").getPaymentMethodSmartList();
variables.saveablePaymentMethodsSmartList.addFilter('activeFlag', 1);
variables.saveablePaymentMethodsSmartList.addFilter('allowSaveFlag', 1);
variables.saveablePaymentMethodsSmartList.addInFilter('paymentMethodType', 'creditCard,giftCard,external,termPayment');
if(len(setting('accountEligiblePaymentMethods'))) {
variables.saveablePaymentMethodsSmartList.addInFilter('paymentMethodID', setting('accountEligiblePaymentMethods'));
}
}
return variables.saveablePaymentMethodsSmartList;
}
我已经有了解析函数声明的语法,但是我需要一个新规则,它可以将doctype注释与函数声明相关联,并且如果存在与之关联的doctype注释,则将函数名称作为单独的标记。
语法看起来像这样:
functionDeclaration
: accessType? typeSpec? FUNCTION identifier
LEFTPAREN parameterList? RIGHTPAREN
functionAttribute* body=compoundStatement
;
答案 0 :(得分:2)
你想要语法规则:
通常,这是上下文依赖。 上下文自由语法无法很好地处理它,这是ANTLR试图用其BNF规则进行近似的东西。实质上,您认为您想要做的是编码解析器很久以前看到的历史记录,以影响现在生成的内容。一般来说这很难。
通常的解决方法就是不要在语法中解决它。代替:
对于docstring-influence-functions名称的特定情况,您可以远离编码远离历史记录。
你需要(恕我直言,丑陋)语法规则看起来像这样:
functionDeclaration: documented_function | undocumented_function ;
documented_function: docstring accessType? typeSpec? FUNCTION
documented_function_identifier rest_of_function ;
undocumented_function: accessType? typeSpec? FUNCTION
identifier rest_of_function ;
rest_of_function: // avoids duplication, not pretty
LEFTPAREN parameterList? RIGHTPAREN
functionAttribute* body=compoundStatement ;
您必须将docstring识别为可由解析器“看到”的显式标记,这意味着修改词法分析器以将注释(例如,空白)中的文档字符串转换为标记。 [这是第一个丑陋的事情]。然后看到这样的文档字符串,词法分析器必须切换到词汇模式,该模式将拾取类似标识符的文本并生成 documentation_function_identifier ,然后切换回正常模式。 [这是第二个丑陋的事情]。你正在做的是从字面上实现一个上下文依赖。
尽管有关上下文依赖性的评论,你可以实现这一目标的原因是A不是很远;它在X的几个标记之内。
所以,你可以这样做。我不会这样做;你试图让解析器做得太多。坚持“通常的解决方案”。 (你会遇到不同的问题:你的A是注释/空白,可能不会被ANTLR存储在树中。你必须解决这个问题;我不是ANTLR专家。)