Я начинаю с хорошо сформированной (и хорошо работающей) грамматики для языка. Переменные, бинарные операторы, вызовы функций, списки, петли, и т.д. Условные К этой грамматики я хотел бы добавить, что я звоню 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
в грамматике испортив поведение парсера [Как-то], и я чувствую, что я игнорирую довольно простой принцип теории языка, который исправит это в jiff, но тот факт, что конфликтов сдвига/сокращения не существует, оставило меня сбитым с толку ,
Есть ли лучший способ (грамматически) написать эти правила? Что мне не хватает? Почему нет конфликтов?
(А вот full grammar file в случае это помогает)
UPDATE: Чтобы уточнить, это язык, который компилируется в код время запуска виртуальной машины, вложена в другую систему - игра , в частности. Он имеет скаляры и списки, и нет сложных типов данных. Когда я говорю, что хочу добавить object
с языком, это на самом деле неправильно. Я не добавляю поддержку пользовательских типов на мой язык.
Объекты, к которым осуществляется доступ с конструкцией object
, фактически являются объектами игры, которые я позволяю языковому процессору получить доступ через промежуточный уровень, который соединяет виртуальную машину с игровым движком. Этот слой предназначен для максимально возможного отграничения определения языка и механики виртуальных машин от реализации и деталей игрового движка.
Так, когда на моем языке я пишу:
player->name
Это только получает кодифицированный компилятор. «player» и «name» не являются традиционными identifier
, потому что они не добавляются в таблицу символов, и ничего не делается с ними во время компиляции, кроме как для перевода запроса на имя игрока в 3-адресный код.
Я бы заменить определение объекта с "объекта: primary_expression '->' id_lookup". –
@Ira Baxter: Это сработает (если исправить проблему), но это не то, что я ищу, потому что токены в каждом объекте не являются нормальными идентификаторами. –
@Chris: Хорошо, как насчет «object: primary_expression» -> «object_name» с добавлением «object_name» к вашему первоначальному определению «primary_expression» [Почему объектные идентификаторы лексически не идентичны другим идентификаторам? Люди вообще отказались от специальных идентификаторов конкретной категории] –