проблема с определением функции в моей грамматике

У меня проблема с определением функции в моей грамматике C, которую можно найти здесь http://www.archive-host.com/files/1959635/24fe084677d7655eb57ba66e1864081450017dd9/cAST.txt, не правильно определяет и не могу на что-то умножить. Код, который я пытаюсь ввести, таков:

int factorielle(int n)
  { int x;
   if ( n == 0)
  return 1;
   else return n*factorielle(n-1);
  }

Определение функции такое:

function_definition
    : declaration_specifiers declarator compound_statement
    | declarator compound_statement
    ;

Declaration_specifiers должен быть связан с int, а декларатор — с factorielle(int n), для этого я заменил это:

direct_declarator
: ID ((direct_declarator '[' ']') | (direct_declarator '(' parameter_type_list ')') | (direct_declarator '(' identifier_list ')') | (direct_declarator '(' ')') )*

с участием

direct_declarator
: ID ((direct_declarator '[' ']') | (direct_declarator '(' parameter_type_list ')') | (direct_declarator '(' identifier_list ')') | (direct_declarator '(' ')')  | '(' parameter_type_list ')' )*

Но это мало помогает.

Что касается умножения, то я не знаю, как обойтись без конфликта. есть ли способ исправить это, пожалуйста?


person Exia0890    schedule 08.03.2013    source источник


Ответы (2)


Вам, вероятно, будет трудно анализировать настоящий код C, используя чистую грамматику с чистым ANTLR.

Причина в том, что некоторые объявления выглядят как законные исполняемые операторы. (Хотя указанный ответ, кажется, касается синтаксических анализаторов LR (1), на самом деле речь идет о синтаксических анализаторах, которые не могут обрабатывать двусмысленность; ANTLR не может).

Единственный способ отличить их друг от друга — использовать контекстную информацию, доступную из более ранних объявлений символов. Таким образом, вам придется собирать типы символов во время разбора и проверять эту информацию в сокращениях правил грамматики, чтобы решить, являются ли такие экземпляры операторами или объявлениями. (Я не знаю, как это реализовать в ANTLR, хотя я считаю, что это возможно).

person Ira Baxter    schedule 09.03.2013
comment
Я понимаю, что вы имеете в виду, что касается контекста, я посмотрю, смогу ли я его выучить. Но входной код обычно прост, пример, который я использовал, должен быть одним из самых сложных, которые будут вводиться в грамматику. Но это правда, у меня много проблем с двусмысленностью. - person Exia0890; 09.03.2013
comment
Трудность с большинством программ (инструментов) заключается в том, что ввод обычно прост, но на самом деле они должны иметь дело с наиболее сложным случаем, чтобы быть полезными на практике. Если у вас нет железного контроля над тем, что люди вручают вашему инструменту, они вручат ему самую уродливую вещь на планете и будут жаловаться, когда он выйдет из строя. Если вы строите игрушку в образовательных целях, вы можете игнорировать все неприятные сложности, пока вы понимаете, где вы жульничаете. - person Ira Baxter; 09.03.2013
comment
Я вижу, кажется, что даже простым заявлением может быть трудно управлять. Но я не думаю, что у меня есть знания о Antlr, чтобы иметь железный контроль над ним, но я попытаюсь. - person Exia0890; 09.03.2013
comment
Конечно, с помощью ANTLR 3 можно разобрать реальный код C. Я написал грамматику ANTLR 2, которая находится на веб-сайте antlr. Вы можете увидеть, как работать с определениями типов в нем, используя семантические предикаты, и как справляться с неоднозначностью объявления/функции, используя синтаксические предикаты. antlr3.org/grammar/cgram - person monty0; 11.03.2013
comment
@ monty0: Да, я считаю, что вы можете сделать это с ANTLR, но у вас должен быть хак для проверки контекста. Это то, что я имел в виду, говоря о том, что с чистой грамматикой этого сделать нельзя. Проблема ОП связана с его реализацией, а не с вашей :-{ - person Ira Baxter; 11.03.2013

Возможно, я нашел решение первой части проблемы, заменив

compound_statement
  : '{' '}'
  | '{' statement_list '}'
  ;

с участием

compound_statement
  : '{' '}'
  | '{' statement_list '}'
  | '{' external_declaration+ '}'
  ;

и добавив это в direct_declarator:

| ID '(' parameter_type_list ')'

Но я не знаю, принесет ли это какие-то конфликты.

person Exia0890    schedule 09.03.2013