Closed Mazdaywik closed 1 year ago
В частной переписке обсудили этот вопрос с Андреем Петровичем Немытых и @TonitaN.
Пришли к выводу, что правильным поведением в этом случае должно быть актуальное поведение crefal
’а + предупреждение на $EXTERN Prout;
.
Однако, в рамках данной заявки я реализую выдачу ошибок во всех перечисленных случаях, т.к. в парсере отсутствует проверка предупреждений. Однако, к местам, где должны выдаваться предупреждения, я добавлю соответствующий комментарий с TODO. При реализации предупреждений ошибки станут предупреждениями.
Ошибки выдаются. В дальнейшем некоторые из них (см. комментарий https://github.com/Mazdaywik/refal-5-framework/issues/9#issuecomment-1257169247) нужно сделать предупреждениями — #11).
Воспроизведение ошибки
Рассмотрим 4 файла:
redudand-externs1.BAD-SYNTAX.ref
:redudand-externs2.BAD-SYNTAX.ref
:Файл
redudand-externs3.BAD-SYNTAX.ref
:Файл
redudand-externs4.BAD-SYNTAX.ref
:Все эти файлы лежат в папке
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 можно будет упростить, удалив из него проверки.
Замечание про встроенные функции
Переопределение встроенной функции
Обе официальные реализации выдают ошибки, если пользователь старается переопределить встроенные функции:
Аналогично ведёт себя и парсер фреймворка:
Здесь всё в порядке, проблемы нет.
$EXTERN
для встроенной функцииАналогично все три реализации (
crefal
,refc
и парсер фреймворка) одинаково ведут себя и в случае объявления встроенной функции как внешней:Все три реализации молча принимают данный файл, не вывода ошибок.
Такое поведение мне кажется неконсистентным — функция в файле может быть или встроенной (нет ни объявлений, ни определений), либо имеет единственное объявление
$EXTERN
, либо единственное определение. А тут возникает исключение из общего правила для имён встроенных функций.Что делать? Если проще будет реализовать общее правило (единственное объявление/определение), то парсер фреймворка вопреки обеим официальным реализациям будет выдавать ошибку на
$EXTERN Prout;
. Если проще будет иначе — сделаю иначе.