Size: a a a

Compiler Development

2019 September 23

VS

Vyacheslav Shebanov in Compiler Development
и это наверное не очень хорошо
источник

M

MaxGraey in Compiler Development
Пусть лучше падает по таймауту, чем мне придётся его самому стопать
источник

VS

Vyacheslav Shebanov in Compiler Development
В общем, мой посыл — тьюринг полнота в системе типов это скорее плохо, чем хорошо. Но кажется, избежать ее настолько сложно, что практически любой язык с достаточно сложной системтой типов в итоге имеет тьюринг-полную систему типов
источник

VS

Vyacheslav Shebanov in Compiler Development
кажется, что только с случаях где люди заморочились именно про это она не является тьюринг полной: agda, idris и хаскель без некоторых экстеншенов
источник

AT

Alexander Tchitchigin in Compiler Development
Vyacheslav Shebanov
кажется, что только с случаях где люди заморочились именно про это она не является тьюринг полной: agda, idris и хаскель без некоторых экстеншенов
Это как бы ответ на вопрос "зачем вообще нужна эта ваша теория типов, нас и без неё неплохо кормят!" 😃
источник

VS

Vyacheslav Shebanov in Compiler Development
+
источник

O

Oriflame Holding AG in Compiler Development
Всем привет, как реализовать схему проверки "на потом" (сам придумал потому что не знаю как вообще это назвать и где про это прочитать) для переменных?

Схема допустим как в Go:
func main() {
 if ABC == 0 { fmt.Println("HELLO") }
}
const ABC = 0

Константа ABC задекларированна после функции main(), и в Go этот код будет рабочий, потому что походу Go проверяет переменную в глобальном скопе в самом последнем моменте этапе парсинга.

Я когда только начал писать транслятор, не учел этот момент, и поэтому как только получал .NAME токен допустим в if выражении я проверял есть ли эта переменная в таблице.
То есть переменная ABC должна была быть задефайнина перед этим самым выражением, перед самой фукнцией, иначе был бы compile time error. То есть код выше не работал бы.

У меня есть два зачаточных варианта, но я не знаю будут ли они работать и нормально ли вообще такое:
*Первый вариант* - все "ненайденные" переменные добавлять в ту же таблицу (таблица это массив переменных, типов, функций и прочего), так как мы не знаем тип переменной  мы добавляет только имя, и ставим placeholder = true, означает что этот плейсхолдер должен быть снят как только точно такая же переменная будет найдена и она будет глобальной, ибо с локальными переменными такая фишка уже не прокатит, парсить все пакеты и прочее, и потом перед этапом компиляции как-то проходится по массиву данных в таблице и искать все placeholder = true переменные (значит что плейсхолдер не был снят и переменная не была найдена), выдавать ошибку мол переменная ".NAME" не найдена там то там то.

*Второй вариант* - сделать приоритет выражений, запускать парсер и искать в первую очередь декларации глобальных переменных, но есть ещё "пакеты", которые импортируются при помощи #include<packagename>; и только как все пакеты будут импортированны и проверены тем же самым методом, до тех пор пока не будет EOF, можно переходить к нашему внешнему пакету для дальнейшей проверки, то есть если идет func конструкция или любая другая конструкция, пропускать её до тех пор пока не наткнемся на EOF или новую декларацию глобальной переменной.

Но это всё походу полная чушь потому что нужно будет два раза подрят парсить один и тот же файл, в обоих случаях, что скажется на производительности.

Я сейчас в полном ступоре, потому что почему-то не учел такой вариант событий, как это называется правильно тоже не знаю, почитать об этом негде(
источник

А

Антон in Compiler Development
Несколько проходов мб?)
источник

K

Konstantin in Compiler Development
Линковщики же делают так
источник

AK

Andrei Kurosh in Compiler Development
Oriflame Holding AG
Всем привет, как реализовать схему проверки "на потом" (сам придумал потому что не знаю как вообще это назвать и где про это прочитать) для переменных?

Схема допустим как в Go:
func main() {
 if ABC == 0 { fmt.Println("HELLO") }
}
const ABC = 0

Константа ABC задекларированна после функции main(), и в Go этот код будет рабочий, потому что походу Go проверяет переменную в глобальном скопе в самом последнем моменте этапе парсинга.

Я когда только начал писать транслятор, не учел этот момент, и поэтому как только получал .NAME токен допустим в if выражении я проверял есть ли эта переменная в таблице.
То есть переменная ABC должна была быть задефайнина перед этим самым выражением, перед самой фукнцией, иначе был бы compile time error. То есть код выше не работал бы.

У меня есть два зачаточных варианта, но я не знаю будут ли они работать и нормально ли вообще такое:
*Первый вариант* - все "ненайденные" переменные добавлять в ту же таблицу (таблица это массив переменных, типов, функций и прочего), так как мы не знаем тип переменной  мы добавляет только имя, и ставим placeholder = true, означает что этот плейсхолдер должен быть снят как только точно такая же переменная будет найдена и она будет глобальной, ибо с локальными переменными такая фишка уже не прокатит, парсить все пакеты и прочее, и потом перед этапом компиляции как-то проходится по массиву данных в таблице и искать все placeholder = true переменные (значит что плейсхолдер не был снят и переменная не была найдена), выдавать ошибку мол переменная ".NAME" не найдена там то там то.

*Второй вариант* - сделать приоритет выражений, запускать парсер и искать в первую очередь декларации глобальных переменных, но есть ещё "пакеты", которые импортируются при помощи #include<packagename>; и только как все пакеты будут импортированны и проверены тем же самым методом, до тех пор пока не будет EOF, можно переходить к нашему внешнему пакету для дальнейшей проверки, то есть если идет func конструкция или любая другая конструкция, пропускать её до тех пор пока не наткнемся на EOF или новую декларацию глобальной переменной.

Но это всё походу полная чушь потому что нужно будет два раза подрят парсить один и тот же файл, в обоих случаях, что скажется на производительности.

Я сейчас в полном ступоре, потому что почему-то не учел такой вариант событий, как это называется правильно тоже не знаю, почитать об этом негде(
Ну так на момент _парсинга_ не важно, объявлен этот идентификатор или нет
источник

K

Konstantin in Compiler Development
Но вообще-то да, это не относится к синтаксическому анализу же
источник

AK

Andrei Kurosh in Compiler Development
А так да - в результате первого прохода наполняются таблицы символов (с учетом областей видимости) и в дальнейших проходах (семантический анализ, кодогенерация) ими можно свободно пользоваться
источник

А

Антон in Compiler Development
Konstantin
Но вообще-то да, это не относится к синтаксическому анализу же
Это уже семантика типа?
источник

O

Oriflame Holding AG in Compiler Development
Ага, понял теперь в какую сторону смотреть и как это называется, спасибо!
источник

K

Konstantin in Compiler Development
Антон
Это уже семантика типа?
Да, конечно
источник

А

Алексей in Compiler Development
Oriflame Holding AG
Всем привет, как реализовать схему проверки "на потом" (сам придумал потому что не знаю как вообще это назвать и где про это прочитать) для переменных?

Схема допустим как в Go:
func main() {
 if ABC == 0 { fmt.Println("HELLO") }
}
const ABC = 0

Константа ABC задекларированна после функции main(), и в Go этот код будет рабочий, потому что походу Go проверяет переменную в глобальном скопе в самом последнем моменте этапе парсинга.

Я когда только начал писать транслятор, не учел этот момент, и поэтому как только получал .NAME токен допустим в if выражении я проверял есть ли эта переменная в таблице.
То есть переменная ABC должна была быть задефайнина перед этим самым выражением, перед самой фукнцией, иначе был бы compile time error. То есть код выше не работал бы.

У меня есть два зачаточных варианта, но я не знаю будут ли они работать и нормально ли вообще такое:
*Первый вариант* - все "ненайденные" переменные добавлять в ту же таблицу (таблица это массив переменных, типов, функций и прочего), так как мы не знаем тип переменной  мы добавляет только имя, и ставим placeholder = true, означает что этот плейсхолдер должен быть снят как только точно такая же переменная будет найдена и она будет глобальной, ибо с локальными переменными такая фишка уже не прокатит, парсить все пакеты и прочее, и потом перед этапом компиляции как-то проходится по массиву данных в таблице и искать все placeholder = true переменные (значит что плейсхолдер не был снят и переменная не была найдена), выдавать ошибку мол переменная ".NAME" не найдена там то там то.

*Второй вариант* - сделать приоритет выражений, запускать парсер и искать в первую очередь декларации глобальных переменных, но есть ещё "пакеты", которые импортируются при помощи #include<packagename>; и только как все пакеты будут импортированны и проверены тем же самым методом, до тех пор пока не будет EOF, можно переходить к нашему внешнему пакету для дальнейшей проверки, то есть если идет func конструкция или любая другая конструкция, пропускать её до тех пор пока не наткнемся на EOF или новую декларацию глобальной переменной.

Но это всё походу полная чушь потому что нужно будет два раза подрят парсить один и тот же файл, в обоих случаях, что скажется на производительности.

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

O

Oriflame Holding AG in Compiler Development
Алексей
AST же строится? Вот можно в узле использование переменной делать ссылку на символ в таблице символов не обязательной (сохраняя при этом имя). А потом во втором проходе (уже по AST) резолвить пустые ссылки по уже полностью построенным таблицам.
Вообще был не AST, а формальная таблица (так я её назвал), там не было дерева который включал себя рекурсивные выражения, была таблица где просто были определенны переменные, функции в качестве массива. Но теперь походу придется пилить AST для большей удобности.
источник

А

Антон in Compiler Development
Oriflame Holding AG
Вообще был не AST, а формальная таблица (так я её назвал), там не было дерева который включал себя рекурсивные выражения, была таблица где просто были определенны переменные, функции в качестве массива. Но теперь походу придется пилить AST для большей удобности.
Можно и таблицу оставить, просто смириться с мыслью что будет несколько проходов которые будут разделяться на синтаксис и семантику
источник

А

Алексей in Compiler Development
Oriflame Holding AG
Вообще был не AST, а формальная таблица (так я её назвал), там не было дерева который включал себя рекурсивные выражения, была таблица где просто были определенны переменные, функции в качестве массива. Но теперь походу придется пилить AST для большей удобности.
Странно.
источник

O

Oriflame Holding AG in Compiler Development
Алексей
Странно.
Да я чтоб сильно с AST не заморачиватся, сделал такую штукенцию )
источник