Проблемы с синтаксическим анализом decaf (объявление переменной в сравнении с конструктором)

Я использую bison (3.0.4) и лексер для реализации (частичной) грамматики языка программирования Decaf. Я только реализую то, что находится внутри класса.

Итак, моя задача проста: сохранить каждое производственное правило (в виде строки) в дереве, а затем просто распечатать его.

Например, если у вас есть следующая строка кода в качестве ввода

class Foo { Foo(int arg1) { some2 a; } }

Вы (должны) получить следующий вывод

<ClassDecl>         --> class identifier <classBody>
<ClassBody>         --> { <VariableDecl>* <ConstructorDecl>* <MethodDecl>* }
<ConstructorDecl>   --> identifier ( <ParameterList> ) <Block>
<ParameterList>     --> <Parameter> <, Parameter>*
<Parameter>         --> <Type> identifier
<Type>              --> <SimpleType>
<SimpleType>        --> int
<Block>             --> { <LocalVariableDecl>* <Statement>* }
<LocalVariableDecl> --> <Type> identifier ;
<Type>              --> <SimpleType>
<SimpleType>        --> identifier

Первая проблема (решенная) заключалась в том, что она анализировала объявление переменной вместо объявления конструктора, хотя у меня нет объявления переменной в области видимости самого класса (т. Е. У меня есть только внутри блока конструктора). Это решено

Тем не менее, если я дам следующее class abc { some1 abc; john doe; } это говорит о том, что syntax error, unexpected SEMICOLON, expecting LP, Итак, символ в строке 19 вызывает проблему.

Вот файл .y (только правило classBody)

class_decl:
  CLASS ID LC class_body RC
  ;


/* FIXME: Gotta add more grammar here */
class_body: var_declmore constructor_declmore method_declmore
  | var_declmore constructor_declmore
  | var_declmore method_declmore
  | constructor_declmore method_declmore
  | method_declmore
  | var_declmore
  | constructor_declmore
  | %empty
  ;


var_declmore: var_decl
  | var_declmore var_decl
  ;


constructor_declmore: constructor_decl
  | constructor_declmore constructor_decl 
  ;

var_decl: type ID SEMICOLON
  | type ID error
  ;

constructor_decl: ID LP parameter_list RP block
  | ID error parameter_list RP block
  ;

Вот суть полного .y файла.

1 ответ

Существенная проблема заключается в том, что constructor_declmore может быть пустым, и что оба var_decl а также constructor_decl можно начать с ID,

Это проблема, потому что перед тем, как парсер сможет распознать constructor_declнужно уменьшить (пусто) constructor_declmore, Но он, очевидно, не может сделать это сокращение, если не знает, что var_declmore закончен.

Поэтому, когда он видит ID он должен выбрать одно из двух действий:

  1. Уменьшить пустой constructor_declmoreтем самым решив, что больше нет var_decls; или же

  2. Сдвинуть ID чтобы начать разбор нового var_decl,

В отсутствие деклараций предшествования (что здесь не поможет), bison / yacc всегда разрешает конфликты сдвига / уменьшения в пользу действия сдвига. Так что в этом случае предполагается, что Foo это ID который начинает var_decl, что приводит к сообщению об ошибке, которое вы заметили.

Следует также учитывать конфликт уменьшения / уменьшения, вызванный грамматикой. Это исходит от method_declmore: method_decl правило, которое конфликтует с другим возможным способом создания method_declmore начиная с пустого method_declmore а затем добавив method_decl,

Другие вопросы по тегам