创建一个ANTLR语法规则,如果它在函数声明上方找到doctype注释,则返回函数名称作为标记

时间:2016-08-02 17:24:45

标签: java coldfusion antlr coldfusion-10

这是我要解析的代码示例。当我覆盖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

  ;

1 个答案:

答案 0 :(得分:2)

你想要语法规则:

  • 如果源中的“远处”是A,
  • ,则返回X. 如果遥远的地方是B(或......),则
  • 返回Y.

通常,这是上下文依赖上下文自由语法无法很好地处理它,这是ANTLR试图用其BNF规则进行近似的东西。实质上,您认为您想要做的是编码解析器很久以前看到的历史记录,以影响现在生成的内容。一般来说这很难。

通常的解决方法就是不要在语法中解决它。代替:

  • 让语法规则产生一个X而不管什么是遥远的,
  • 在解析时构建一个树(ANTLR为你做这个);这不仅捕获X而且捕获有关已解析实体的所有内容,包括远离
  • 的A的令牌
  • 走过树,如果树中包含A(通常远在树中),则将找到的X解释为Y.

对于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专家。)