2015-05-18 3 views
3

Как я могу улучшить свою грамматику парсера, чтобы вместо создания AST, содержащего пару правил decFunc для моего тестового кода. Он создаст только один, а sum станет вторым корнем. Я попытался решить эту проблему несколькими разными способами, но всегда получаю левую рекурсивную ошибку. Это мой код тестирования:ANTLR 4 Parser Grammar

f :: [Int] -> [Int] -> [Int] 
f x y = zipWith (sum) x y 
sum :: [Int] -> [Int] 
sum a = foldr(+) a 

Это моя грамматика: Это изображение, которое имеет в этой связи два decFunc http://postimg.org/image/w5goph9b7/

prog  : stat+; 

stat  : decFunc | impFunc ; 


decFunc  : ID '::' formalType (ARROW formalType)* NL impFunc 
      ; 

anotherFunc : ID+; 


formalType : 'Int' | '[' formalType ']' ; 


impFunc  : ID+ '=' hr NL 

      ; 


hr   : 'map' '(' ID* ')' ID* 
       | 'zipWith' '(' ('*' |'/' |'+' |'-') ')' ID+ | 'zipWith' '(' anotherFunc ')' ID+ 
       | 'foldr' '(' ('*' |'/' |'+' |'-') ')' ID+ 
       | hr op=('*'| '/' | '.&.' | 'xor') hr | DIGIT 
       | 'shiftL' hr hr | 'shiftR' hr hr 
       | hr op=('+'| '-') hr | DIGIT 
       | '(' hr ')' 
       | ID '(' ID* ')' 
       | ID 
       ; 
+0

Какой желаемый выход? Не имеет смысла говорить «создание одного вместо двух« decFunc ». Попробуйте создать AST так же, как вы хотите. – Mephy

+0

@Mephy Я улучшил свой вопрос. Я в основном пытаюсь сделать сумму ссылкой на другой стат, который может быть декларацией или реализацией. Однако сумма - это только первое слово декларации или реализации. Как я могу это сделать? это то, о чем я прошу. Некоторые предлагают посмотреть. Но я не знаю, как это сделать. –

+0

Все еще неясно, что вы просите. Ваш тестовый ввод содержит два экземпляра контента, которые будут соответствовать правилу 'decFunc'.Сгенерированное ** дерево синтаксического анализа ** точно показывает: два поддерева, каждый из которых имеет экземпляр 'deFunc' в качестве корня. Antlr v4 не будет создавать истинный АСТ, где 'f' и' sum' являются корнями отдельных поддеревьев, если это то, что вы ищете. – GRosenberg

ответ

3

Ваш входной тест содержит два экземпляра контента, который будет соответствуют правилу decFunc. Сгенерированное дерево разбора показывает именно это: два поддерева, каждый из которых имеет deFunc в качестве корня.

Antlr v4 не производит истинный АСТ, где f и sum являются корнями отдельных поддеревьев.

Есть ли что я могу сделать с грамматикой, чтобы сделать как f и sum корни - Jonny Magnam

не непосредственно в v4 грамматике Antlr. Вы можете:

  1. переключиться на Antlr v3 или другой инструмент анализатора и определить сгенерированный АСТ, как вы пожелаете.
  2. Пройдите синтаксический анализ Antlr v4 и создайте отдельный АСТ вашей желаемой формы.
  3. просто используйте синтаксический анализ непосредственно с осознанием того, что он информативно эквивалентен классически определенному АСТ, и реализация обеспечивает ряд практических преимуществ.

В частности, стандартный академический AST изменчив, а это означает, что каждый (или все, кроме первого) визитера на заказ, не генерируется, и что любое изменение в базовой грамматике или временная структура AST потребует пересмотра и, вероятно, изменится на каждого последующего посетителя и на их реализованную логику.

Parse-tree Antlr v4 по существу неизменен, что позволяет накапливать украшения для узлов дерева без потери реляционной целостности. Все посетители используют общую базовую структуру, что значительно снижает хрупкость из-за изменений грамматики и эффектов предыдущих выполненных посетителей. В практическом плане древовидные конструкции легко конструируются, быстро и независимо друг от друга, за исключением случаев, когда это явно желательно. Они могут добиться большего разделения проблем при проектировании и упрощения обслуживания кода на практике.

Выберите нужный инструмент для всей работы, каким бы способом вы ее не определяли.

+0

Спасибо за ваше драгоценное время и ваш ответ. Это помогло мне осознать, что если я собираюсь продолжить ANTLR4, я должен согласиться с тем, что такое АСТ. Я хотел бы спросить вас, какой из них вы предпочитаете для воплощения переводчика слушателем или посетителем. В переводе будет создан еще один код, который не требует вычисления. –

+0

Единственная практическая разница между посетителем и слушателем заключается в том, что посетитель передает объект возврата, а слушатель - ничего. В некоторых случаях возвращаемый объект может быть полезен. На самом деле вам решать, помогает ли это в вашем конкретном дизайне. – GRosenberg

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