Почему гибкость Форта делает грамматику неуместной для нее?

10

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

Это подводит меня к теме этого поста. Я читал статью в Википедии о Forth , основанном на стеке языке, который использует выражения в стиле постфикса. В статье я увидел следующее утверждение:

Гибкость Forth делает статическую грамматику BNF неуместной, и у нее нет монолитного компилятора. Расширение компилятора требует только написания нового слова вместо изменения грамматики и изменения базовой реализации.

Насколько я понимаю, в «Forth lingo» термин «слово» кажется синонимом «подпрограммы». Учитывая это, приведенное выше утверждение кажется странным. Почему именно способность создавать новые функции в Forth делает формальную грамматику для Forth неуместной? Зачем вам нужно переписывать грамматику для каждой новой подпрограммы, которую вы определяете? Как написание нового слова в среде означает расширение компилятора? Вышеприведенное утверждение похоже на то, что формальная грамматика не подходит для Python, потому что вы можете определять новые функции.

Фактически, я решил попытаться написать грамматику стиля BNF для простого подмножества Forth ниже:

program        ::= stmt+
stmt           ::= func | expr
func           ::= ':' expr+ ';'
expr           ::= INTEGER | word
word           ::= ('+' | '-' | '*' | '/' )

Вышеприведенная грамматика, по-видимому, охватывает действительное подмножество операторов Forth, и, кажется, не так сложно расширить ее, чтобы охватить все действительные операторы на языке Forth. Кроме того, если синтаксический анализатор компилятора реализует вышеуказанную грамматику, я не вижу, как компилятор будет расширяться. Компилятор просто добавит любые новые слова в свою среду . Только среда изменилась. Кажется, что приведенный выше фрагмент из Википедии объединяет подчеркивающий код, который составляет компилятор (который не изменяется), со средой компилятора (которая действительно изменяется).

Итак, почему аблиции Форта для определения новых слов (подпрограмм) делают неуместными для письменной грамматики?

Христианский декан
источник
1
«Неуместное» является сильным словом в этом контексте. Лучшее слово, вероятно, будет «ненужным».
Роберт Харви
1
О, ладно, @RobertHarvery. Однако если бы это было так, то приведенная мною выдержка, похоже, применима к большинству языков. Технически грамматика никогда не нужна , но хорошо иметь ее, особенно когда парсеры пишут вручную.
Кристиан Дин
Но в большинстве языков синтаксический анализатор не является простой библиотекой времени выполнения, которую можно изменить с помощью пользовательского кода, что влияет на анализ следующей строки.
Йорг Миттаг

Ответы:

10

«Нормальное» слово - это просто подпрограмма.

... но вы можете написать определяемое пользователем слово , которое изменит работу компилятора. Например, определение обычно начинается с двоеточия (":") и заканчивается точкой с запятой (";"). Но если вы хотите, вы можете (например) изменить то, что делает двоеточие, и в процессе изменить то, как определение слова «скомпилировано», тем самым изменив работу компилятора и изменив грамматику распознаваемого языка.

Вот почему говорится, что грамматика неуместна - грамматика может буквально меняться от одной части программы к другой. Загрузка словаря может изменить не только подпрограммы, имена которых в настоящее время распознаются, но и грамматику, которая анализируется при определении нового слова.

Джерри Гроб
источник
2
Вы уверены, что это свойство Forth действительно меняет грамматику, а не только семантику?
Док Браун
@DocBrown: Большинству людей, которые используют Forth, это очень нравится, поэтому они обычно вносят только самые минимальные изменения, необходимые для выполнения поставленной задачи. Кто-то, кто был достаточно амбициозным (и достаточно сумасшедшим), мог полностью изменить синтаксис, если бы захотел - например, использовать инфиксную нотацию вместо постфикса, если он захотел достаточно сильно.
Джерри Гроб
@DocBrown Какую грамматику вы могли бы написать, которая позволила бы мне написать интерпретатор C на Forth, а затем внезапно переключиться на C в середине программы?
user253751
@immibis: хорошо, мой вопрос - действительно ли Форт допускает что-то подобное? Из этой связанной статьи мне это не совсем понятно.
Док Браун
@DocBrown Да, это так. Вы можете запустить свой код во время компиляции, это означает, что если вы хотите, вы можете полностью взять на себя управление компилятором. По сути, вы можете запустить свой компилятор / интерпретатор C в середине компилятора / интерпретатора Forth. (хотите ли вы в конечном итоге вернуться обратно в Форт или нет
решать
3

В Forth вы можете запускать код во время компиляции.

В частности, вы можете запустить код, который потребляет слова из ввода. Например, вы можете написать компилятор C на Forth, а затем вызвать его во время компиляции, а затем написать остальную часть вашей программы на C.

Чаще всего вы можете определить слова, которые читают аргументы из исходного кода. Традиционно вы должны читать слова так же, как это делает компилятор, но это не обязательно.

Например, ."слово (которое печатает строку) не читается до следующего пробела, оно читается до следующего ". Если вы попытаетесь проанализировать код : PRINTHELLO ." Hello ; : func2 world!" ;без особого случая .", вы обнаружите, что он не был проанализирован правильно.

Вы , конечно , можете добавить специальный случай для ."к вашей грамматике, но грамматика все равно будет неверной , если программист определяет свое собственное слово , как ."- например , вот один: : MY_PRINT POSTPONE ." ; IMMEDIATE. Это слово эквивалентно ."; Я могу написать, MY_PRINT Hello ; world! "и ваша грамматика должна быть в состоянии разобрать ее. Удачи с этим.

user253751
источник