Mazdaywik / refal-5-framework

Фреймворк для трансформации программ на Рефале-5
https://mazdaywik.github.io/refal-5-framework
MIT License
3 stars 0 forks source link

Ошибки на избыточные `$EXTERN`’ы #9

Closed Mazdaywik closed 1 year ago

Mazdaywik commented 1 year ago

Воспроизведение ошибки

Рассмотрим 4 файла:

Все эти файлы лежат в папке tests/parser, т.е. могут быть запущены скриптом run.bat или run.sh.

Посмотрим, как эти файлы компилируются официальными реализациями Рефала:

Запуск refc ``` …\refal-5-framework\tests\parser>refc redudand-externs1.BAD-SYNTAX.ref Refal-5 Compiler. Version PZ Oct 29 2004 Copyright: Refal Systems Inc. …\refal-5-framework\tests\parser>refc redudand-externs2.BAD-SYNTAX.ref Refal-5 Compiler. Version PZ Oct 29 2004 Copyright: Refal Systems Inc. …\refal-5-framework\tests\parser>refc redudand-externs3.BAD-SYNTAX.ref Refal-5 Compiler. Version PZ Oct 29 2004 Copyright: Refal Systems Inc. Error: 201. Doubly defined function Foo . May be the function is built. on line 2. Error: 103. Expected ';' on line 2. 2 errors found in function 2 syntax errors found. …\refal-5-framework\tests\parser>refc redudand-externs4.BAD-SYNTAX.ref Refal-5 Compiler. Version PZ Oct 29 2004 Copyright: Refal Systems Inc. Error: 201. Doubly defined function Foo . May be the function is built. on line 1. Error: 103. Expected ';' on line 1. 2 errors found in function 2 syntax errors found. ```

Компилятор refc первые два файла откомпилировал, на два других выдал ошибки.

Запуск crefal ``` …\refal-5-framework\tests\parser>crefal redudand-externs1.BAD-SYNTAX.ref Copyright (C): RefalScope Project, 2004-2018 Error on line 2: Redefinition of function Go . crefal: 1 syntax error found. …\refal-5-framework\tests\parser>crefal redudand-externs2.BAD-SYNTAX.ref Copyright (C): RefalScope Project, 2004-2018 Error on line 3: Redefinition of external function L . crefal: 1 error found in function L crefal: 1 syntax error found. …\refal-5-framework\tests\parser>crefal redudand-externs3.BAD-SYNTAX.ref Copyright (C): RefalScope Project, 2004-2018 Warning: Repeated external declaration of Foo on line 2 . Warning: Repeated external declaration of Bar on line 2 . crefal: 2 warnings found. …\refal-5-framework\tests\parser>crefal redudand-externs4.BAD-SYNTAX.ref Copyright (C): RefalScope Project, 2004-2018 Warning: Repeated external declaration of Foo on line 1 . Warning: Repeated external declaration of Bar on line 1 . crefal: 2 warnings found. ```

Компилятор crefal, наоборот, первые два файла отверг, два последних откомпилировал, выдав, однако, предупреждение.

Актуальная реализация парсера (85fb3dd90cb69f1b4b017c69c9c3fad6484dc2f7) все четыре файла принимает:

Запуск tests\parser\run.cmd ``` D:\Mazdaywik\Documents\refal-5-framework\tests\parser>run.cmd redudand-externs1.BAD-SYNTAX.ref Refal-5 Compiler. Version PZ Oct 29 2004 Copyright: Refal Systems Inc. Parsing redudand-externs1.BAD-SYNTAX.ref... redudand-externs1.BAD-SYNTAX.ref: PARSER MISSED ERRORS! AST: (Function (1 1 redudand-externs1.BAD-SYNTAX.ref)(Go)Entry (()RETURN ())) (Extern ((2 9 redudand-externs1.BAD-SYNTAX.ref)Go)) Parser failed, see __err.txt for details D:\Mazdaywik\Documents\refal-5-framework\tests\parser>run.cmd redudand-externs2.BAD-SYNTAX.ref Refal-5 Compiler. Version PZ Oct 29 2004 Copyright: Refal Systems Inc. Parsing redudand-externs2.BAD-SYNTAX.ref... redudand-externs2.BAD-SYNTAX.ref: PARSER MISSED ERRORS! AST: (Extern ((1 9 redudand-externs2.BAD-SYNTAX.ref)L)) (Function (2 1 redudand-externs2.BAD-SYNTAX.ref)(Go)Entry (()RETURN ((Call (2 15 redudand-externs2.BAD-SYNTAX.ref)(L))))) (Function (3 1 redudand-externs2.BAD-SYNTAX.ref)(L)Local (()RETURN ())) Parser failed, see __err.txt for details D:\Mazdaywik\Documents\refal-5-framework\tests\parser>run.cmd redudand-externs3.BAD-SYNTAX.ref Refal-5 Compiler. Version PZ Oct 29 2004 Copyright: Refal Systems Inc. Parsing redudand-externs3.BAD-SYNTAX.ref... redudand-externs3.BAD-SYNTAX.ref: PARSER MISSED ERRORS! AST: (Extern ((1 9 redudand-externs3.BAD-SYNTAX.ref)Foo)((1 14 redudand-externs3.BAD-SYNTAX.ref)Bar)) (Extern ((2 9 redudand-externs3.BAD-SYNTAX.ref)Foo)((2 14 redudand-externs3.BAD-SYNTAX.ref)Bar)) (Function (4 1 redudand-externs3.BAD-SYNTAX.ref)(Go)Entry (()RETURN ((Call (4 15 redudand-externs3.BAD-SYNTAX.ref)(Foo))(Call (4 21 redudand-externs3.BAD-SYNTAX.ref)(Bar))))) Parser failed, see __err.txt for details D:\Mazdaywik\Documents\refal-5-framework\tests\parser>run.cmd redudand-externs4.BAD-SYNTAX.ref Refal-5 Compiler. Version PZ Oct 29 2004 Copyright: Refal Systems Inc. Parsing redudand-externs4.BAD-SYNTAX.ref... redudand-externs4.BAD-SYNTAX.ref: PARSER MISSED ERRORS! AST: (Extern ((1 9 redudand-externs4.BAD-SYNTAX.ref)Foo)((1 14 redudand-externs4.BAD-SYNTAX.ref)Bar)((1 19 redudand-externs4.BAD-SYNTAX.ref)Foo)((1 24 redudand-externs4.BAD-SYNTAX.ref)Bar)) (Function (3 1 redudand-externs4.BAD-SYNTAX.ref)(Go)Entry (()RETURN ((Call (3 15 redudand-externs4.BAD-SYNTAX.ref)(Foo))(Call (3 21 redudand-externs4.BAD-SYNTAX.ref)(Bar))))) Parser failed, see __err.txt for details ```

Ожидаемое поведение

Неочевидно, т.к. обе официальные реализации друг другу противоречат, а в документации об этом нюансе явно ничего не говорится.

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

Кроме того, тогда реализация будет совместимой с Рефалом-05, который в этих случаях уже выдаёт ошибки, а значит, парсер Рефала-05 можно будет упростить, удалив из него проверки.

Замечание про встроенные функции

Переопределение встроенной функции

Обе официальные реализации выдают ошибки, если пользователь старается переопределить встроенные функции:

$ENTRY Prout { = }
…\refal-5-framework\tests\parser>refc builtin-redefine-entry.BAD-SYNTAX.ref
Refal-5 Compiler. Version PZ Oct 29 2004
Copyright: Refal Systems Inc.
Error: 201. Doubly defined function Prout . May be the function is built. on line     1.
Error: 102. Expected '}'  on line     1.
2 errors found in function Prout
2 syntax errors found.

…\refal-5-framework\tests\parser>crefal builtin-redefine-entry.BAD-SYNTAX.ref
Copyright (C): RefalScope Project, 2004-2018
Error on line 1: Redefinition of built-in function Prout .
crefal: 1 error found in function Prout
crefal: 1 syntax error found.

Аналогично ведёт себя и парсер фреймворка:

D:\Mazdaywik\Documents\refal-5-framework\tests\parser>run builtin-redefine-entry.BAD-SYNTAX.ref
Refal-5 Compiler. Version PZ Oct 29 2004
Copyright: Refal Systems Inc.
Parsing builtin-redefine-entry.BAD-SYNTAX.ref...
builtin-redefine-entry.BAD-SYNTAX.ref: errors was expected, found by parser:
builtin-redefine-entry.BAD-SYNTAX.ref:1:1:Redefinition of builtin function Prout

Здесь всё в порядке, проблемы нет.

$EXTERN для встроенной функции

Аналогично все три реализации (crefal, refc и парсер фреймворка) одинаково ведут себя и в случае объявления встроенной функции как внешней:

…
$EXTERN Prout;
…

Все три реализации молча принимают данный файл, не вывода ошибок.

Такое поведение мне кажется неконсистентным — функция в файле может быть или встроенной (нет ни объявлений, ни определений), либо имеет единственное объявление $EXTERN, либо единственное определение. А тут возникает исключение из общего правила для имён встроенных функций.

Что делать? Если проще будет реализовать общее правило (единственное объявление/определение), то парсер фреймворка вопреки обеим официальным реализациям будет выдавать ошибку на $EXTERN Prout;. Если проще будет иначе — сделаю иначе.

Mazdaywik commented 1 year ago

В частной переписке обсудили этот вопрос с Андреем Петровичем Немытых и @TonitaN.

Пришли к выводу, что правильным поведением в этом случае должно быть актуальное поведение crefal’а + предупреждение на $EXTERN Prout;.

Однако, в рамках данной заявки я реализую выдачу ошибок во всех перечисленных случаях, т.к. в парсере отсутствует проверка предупреждений. Однако, к местам, где должны выдаваться предупреждения, я добавлю соответствующий комментарий с TODO. При реализации предупреждений ошибки станут предупреждениями.

Mazdaywik commented 1 year ago

Ошибки выдаются. В дальнейшем некоторые из них (см. комментарий https://github.com/Mazdaywik/refal-5-framework/issues/9#issuecomment-1257169247) нужно сделать предупреждениями — #11).