#antlr #antlr3 #antlrworks
#antlr #antlr3 #antlrworks
Вопрос:
[11:45:19] warning(200): mygrammar.g:14:57: Decision can match input such as "','" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
[11:45:19] warning(200): C:UsersJarrod Robersonmygrammar.g:14:57: Decision can match input such as "','" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input
Я хочу иметь возможность вкладывать функции внутрь других функций.
myfunction(x) ->
sqr(a) -> a * a,
y -> sqr(x).
вот строка, на которую он жалуется
function : ID '(' args ')' '->' statement (',' statement)* ;
и вот что он рассматривает в качестве альтернативы
statement : ATOM
| expression
| assignment
| function
;
Я использую .
в качестве правила завершения моего оператора
program : (statement'.')*;
Вот как выглядит диаграмма synatx в ANTLRWorks
(источник: vertigrated.com)
Мне действительно нравится, когда вещи компилируются / работают без каких-либо предупреждений. Как мне устранить это условие предупреждения?
Ответ №1:
Джаррод Роберсон писал:
Мне действительно нравится, когда вещи компилируются / работают без каких-либо предупреждений. Как мне устранить это условие предупреждения?
Ваш анализатор может анализировать следующие входные данные:
f(x)-> g(y)-> y*y, x=y
в двух разных деревьях синтаксического анализа:
и:
Вы можете исправить это, заставив анализатор заглядывать вперед и убедиться, что есть ',' statement
что-то впереди, прежде чем фактически сопоставлять эти правила. Вы можете сделать это, используя синтаксический предикат ( (...)=>
часть) с указанным правилом внутри:
function
: ID '(' args ')' '->' statement ((',' statement)=> ',' statement)*
;
Однако вам не нужен предикат, если в вашем function
правиле есть какой-то маркер «end», который вы не определили. Из ваших предыдущих вопросов и вашего примера:
myfunction(x) ->
sqr(a) -> a * a,
y = sqr(x).
кажется, вы используете '.'
как конец function
. Если вы добавите это в свое function
правило:
function
: ID '(' args ')' '->' statement (',' statement)* '.'
;
вам вообще не нужен предикат.
Комментарии:
1. @JarrodRoberson, не стесняйтесь публиковать новый вопрос по этому поводу (если вы застряли на нем, то есть …).
2.
.
в конце функции является частью моегоprogram
правила.program : (statement'.')*;
не является частью правила функции, таким образом, оно непротиворечиво.3. @JarrodRoberson, а, понятно. Глядя на изображения дерева, я надеюсь, становится ясно, почему ANTLR жалуется: у
function
также должен быть очевидный конец. Я полагаю, что при использовании предиката будет создано дерево с первого изображения (и поэтому дерево с изображения 2 никогда не может быть создано!).4. Я понял, что мой пример strawman был неправильным, в нем должно быть
->
где=
находится.5. @JarrodRoberson,
->
и=
здесь не проблема. Отсутствие посторонних символов делает вашу грамматику неоднозначной. Вы понимаете, что анализатор может использовать две «дороги» во время синтаксического анализа"f(x)-> g(y)-> y*y, x=y"
(см. Изображения)? Это потому, что вы явно не определили, когда afunction
заканчивается. Поскольку вы этого не сделали, последнее утверждениеx=y
(илиx->y
, это не имеет значения) может относиться к функцииf
, но также и к функцииg
. Добавляя предикат, вы просто подавляете предупреждение, в то время как вам следует обратиться к нему должным образом (исправить грамматику / язык).