2016-08-02 4 views
1

Это пример кода, который я хочу проанализировать. Я хочу getSaveable PaymentMethodsSmartList() как токен, когда я перезаписываю функцию в файле parserBaseListener.java, созданном ANTLR.Создайте правило грамматики ANTLR, которое возвращает имя функции в качестве токена, если находит комментарий doctype над объявлением функции

/** @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 с функцией декларации и дать имя функции как отдельный знак, если есть доктайп комментарий, связанный с ним.

грамматика выглядит следующим образом:

functionDeclaration 
    : accessType? typeSpec? FUNCTION identifier 
    LEFTPAREN parameterList? RIGHTPAREN 
    functionAttribute* body=compoundStatement 

    ; 
+0

Beacuse I хочу показать код, который я разбираю. Вы можете помочь мне с грамматиком? –

+0

Точка зрения Ира, 'public any function' is not ColdFusion –

+0

@JamesAMohler - это * функция CF (в cfscript) ;-). Конечно, это звучит, как вопрос в конечном счете о синтаксисе Java. – Leigh

ответ

2

Вы хотите правила грамматики, что:

  • возвращение X, если что-то "далеко" в источнике является A,
  • возвращается, если что-то Y далеко находится B (или ...).

В общем, это контекстная зависимость. Он плохо обрабатывается контекстными бесплатными грамматиками, что ANTLR пытается аппроксимировать своими правилами BNF. В сущности, то, что вы думаете, что вы хотите сделать, - это кодировать историю того, что видел парсер давно, влиять на то, что сейчас производится. Как правило, это сложно.

Обычное решение чего-то вроде этого - не обращаться к нему в грамматике вообще. Вместо этого:

  • есть правила грамматики производят X независимо от того, что находится далеко,
  • построить дерево, как вы разбираете (ANTLR делает это для вас); это захватывает не только X, но и все, что касается анализируемой сущности, включая маркеры для A, которые находятся далеко.
  • Пройдитесь по дереву, интерпретируя найденный X как Y, если дерево содержит A (обычно вдали от дерева).

Для вашего конкретного случая имени функции-dorsstring-влияния вы, вероятно, можете уйти с кодировкой вдали от истории.

Вам нужны (ИМХО, уродливые) правила грамматики, которые выглядят примерно так:

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 ; 

Вы должны признать строку документации в качестве явных маркеров, который может быть «видели» анализатор, что означает, модифицируя lexer, чтобы сделать docstrings из комментариев (например, пробелов) в токены. [Это первая уродливая вещь]. Затем, увидев такую ​​docstring, лексер должен переключиться на лексический режим, который будет получать текст, подобный идентификатору, и произвести documented_function_identifier, а затем вернуться в обычный режим. [Это вторая уродливая вещь]. То, что вы делаете, реализует буквально зависимость от контекста.

Причина, по которой вы можете это сделать, несмотря на мои замечания о зависимости от контекста, заключается в том, что A не очень далеко; он находится в пределах нескольких токенов X.

Итак, вы можете сделать это так. Я бы этого не сделал; вы пытаетесь сделать парсер слишком много. Придерживайтесь «обычного решения».(У вас будет другая проблема: ваш A является комментарием/пробелом и, вероятно, не сохраняется в дереве ANTLR. Вам придется это решить, я не эксперт ANTLR.)

 Смежные вопросы

  • Нет связанных вопросов^_^