Я начинаю с хорошо сформированной (и хорошо работающей) грамматики для языка.Переменные, бинарные операторы, вызовы функций, списки, циклы, условные выражения и т. Д. К этой грамматике я хотел бы добавить то, что я называю конструкцией object
:
object
: object_name ARROW more_objects
;
more_objects
: object_name
| object_name ARROW more_objects
;
object_name
: IDENTIFIER
;
Дело в том, чтобывозможность доступа к скалярам, вложенным в объекты.Например:
car->color
monster->weapon->damage
pc->tower->motherboard->socket_type
Я добавляю object
как primary_expression
:
primary_expression
: id_lookup
| constant_value
| '(' expression ')'
| list_initialization
| function_call
| object
;
Теперь вот пример сценария:
const list = [ 1, 2, 3, 4 ];
for var x in list {
send "foo " + x + "!";
}
send "Done!";
До добавления нетерминала object
в качестве primary_expression
все это солнце и щенки.Даже после того, как я добавлю это, Бизон не жалуется.Не сообщается о сдвиге и / или уменьшении конфликтов.И сгенерированный код компилируется без звука.Но когда я пытаюсь запустить приведенный выше пример сценария, мне говорят error on line 2: Attempting to use undefined symbol '{' on line 2.
Если я изменю сценарий на:
var list = 0;
for var x in [ 1, 2, 3, 4 ] {
send "foo " + x + "!";
}
send "Done!";
Тогда я получу error on line 3: Attempting to use undefined symbol '+' on line 3.
Очевидно, что присутствие object
в грамматике портит поведение синтаксического анализатора [SOMEhow], и я чувствую, что игнорирую довольно простой принцип теории языка, который исправит это в один миг, но тот факт, чтоРазве любые конфликты сдвига / уменьшения не оставили меня в замешательстве.
Есть ли лучший (грамматически) способ написать эти правила?Что мне не хватает?Почему нет никаких конфликтов?
(А вот и полный файл грамматики , если он помогает)
ОБНОВЛЕНИЕ: Кпоясните, этот язык, который компилируется в код, выполняемый виртуальной машиной, встроен в другую систему, в частности, в игру.У него есть скаляры и списки, и нет сложных типов данных.Когда я говорю, что хочу добавить object
s к языку, это на самом деле неправильно.Я не добавляю поддержку пользовательских типов в свой язык.
Объекты, к которым осуществляется доступ с помощью конструкции object
, на самом деле являются объектами из игры, к которым я предоставляю доступ языковому процессору через промежуточный слой.который соединяет виртуальную машину с игровым движком.Этот слой предназначен для того, чтобы максимально отделить определение языка и механику виртуальной машины от реализации и деталей игрового движка.
Поэтому, когда на моем языке я пишу:
player->name
Это кодируется только компилятором.«player» и «name» не являются традиционными identifier
s, потому что они не добавляются в таблицу символов, и с ними ничего не делается во время компиляции, кроме как для преобразования запроса имени игрока в 3-адресный код.