Использование ANTLR4 для создания функций без аргументов - PullRequest
0 голосов
/ 11 ноября 2018

Я все еще новичок в ANTLR4 и пытаюсь добиться следующего

У меня есть бизнес-правила, которые состоят из логической операции (A = 'текст' или B <1) и getDataDB </p>

функция getDataDB не принимает никаких аргументов. функция извлекает некоторые данные для проверки и возвращает либо true, либо false.

моя грамматика ниже

   /*
 * Test grammar
 */

grammar FunctionRule;

parse: expr EOF
    ; 


expr
 : expr binop expr                  #logicalExpression
 | lhs=VARIABLE compop rhs=VARIABLE #variableExpression
 | lhs=VARIABLE compop rhs=STRING   #stringExpression
 | lhs=VARIABLE compop rhs=NUMBER   #numberExpression
 | TRUE                             #booleanTrue
 | FALSE                            #booleanFalse
 | function                         #functionExpression
 | VARIABLE                         #booleanVariable
 | LEFTPAREN expr RIGHTPAREN        #enclosedExpression
 ;

binop : AND | OR
 ;

compop: EQUAL | LT | GT | LTE | GTE | NE
      ;

function  : ID {System.out.println("HELLLL");};



TRUE:       'true' | 'TRUE'  ;
FALSE:      'false' | 'FALSE';
STRING:     '"'   ~([\t\n\r]| '"')* '"'
     ;
ID : [getDataDB];
LEFTPAREN:  '(';
RIGHTPAREN: ')';
EQUAL     : '=' | 'EQ';
LT        : '<' | 'LT';
GT        : '>' | 'GT';
LTE       : '<=' | 'LE';
GTE       : '>=' | 'GE';
NE        : '!=' | 'NE';
AND       : 'AND' | '&' | 'and';
OR        : 'OR' | 'or' | '|';
VARIABLE  : [a-zA-Z]+[a-zA-Z0-9_.-]*;
NUMBER  : [0-9]+ ('.'[0-9]+)?;
SPACE     : [ \t\r\n] -> skip;

Когда я генерирую классы из грамматики, я не вижу ничего, связанного с функцией.

1 - как правильно определить функцию в файле грамматики.

2 - где я могу поместить код для этой функции после создания классов, это только в предложении действия, есть ли способ поместить имя класса в грамматику, где я могу поместить реализацию

Спасибо за помощь!

1 Ответ

0 голосов
/ 12 ноября 2018
ID : [getDataDB];

Это означает, что ID соответствует одной букве, которая может быть любой из g, e, t, D, a или B. То, что вы, вероятно, хотели, это ID: 'getDataDB';, который соответствует строке getDataDB. Обратите внимание, что называть это ID очень вводящим в заблуждение.

где я могу поставить код для этой функции

Вы пишете переводчиком с помощью посетителя? Затем вы поместите код в метод visitFunction или, скорее, в метод getDataDB, который вы вызываете из visitFunction, если имя функции будет равно getDataDB (сейчас это всегда будет так, но я Я полагаю, вы в конечном итоге хотите ввести более одной функции).

В качестве альтернативы вы можете также немного по-другому структурировать свою грамматику (убрав правило идентификатора):

function : 'getDataDB' # GetDataDB
         | 'otherFunction' # OtherFunction
         ;

Тогда вы можете определить функции в visitGetDataDB и visitOtherFunction соответственно.

Все это предполагает, что вы хотите, чтобы имена функций были ключевыми словами (что подразумевает, что не может быть определяемых пользователем функций). Если вы этого не сделаете, у вас не должно быть отдельных токенов для имен функций, поэтому функции и переменные с нулевым аргументом становятся неразличимыми синтаксически (если только вы не добавите требование добавить () для функций, но это не похоже на то, что вы хочу). Таким образом, у вас должно быть только одно правило, которое может быть либо переменной, либо функцией с нулевым аргументом, а затем проверить, является ли данный идентификатор именем функции в visitVariableOrNullaryFunction (для краткости, возможно, вы просто вызовете visitVariable) .

...