2014-11-13 7 views
1

Я разрабатываю новый язык, и я следую традиционному подходу: , так что есть лексер, парсер, аш и виртуальная машина, которая выполняет байт-код.Расширяет мой язык во время выполнения

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

Мне было бы интересно, чтобы конечный пользователь мог расширить язык, чтобы пользователь мог добавить функцию operator ++, чтобы создать свой собственный оператор post increment. Я не уверен в правильном способе продолжения работы, потому что парсер не может заранее знать всех операторов, которых пользователь может добавить, поэтому я спрашиваю о правильном подходе.

+0

По существу перегрузка операторов превращает операторов в вызовы функций, но очень мало языков позволяют добавлять новые операторы из-за точной проблемы, о которой вы заявляете; даже C++, известный своей философией «Kitchen sink included», позволяет только перегрузить некоторые существующие операторы, и их поведение синтаксического анализа не может быть изменено. – bcrist

+0

Я очень люблю подход Scala, где все методы - это операторы и наоборот. – lmm

ответ

1

Вы можете сделать это Swift так: есть заявления оператора в вашей грамматике

В Swift он выглядит следующим образом:

infix operator SomeToken { associativity left precedence 150 } 

Это говорит Swift парсер, который SomeToken будет лево-ассоциативным, инфикс оператора, и что в любом решении, основанном на приоритетах, вес этого оператора равен 150. Другие операторы будут иметь более высокие, более низкие или равные показатели приоритета, и это будет направлять парсер при создании АСТ

0

Например, в C# список операторов, которые могут быть перегружены, известен заранее, и перегрузка всегда указывается с помощью специального ключевого слова operator, так что уже известно парсеру, что пользователь «добавляет» оператора.
См http://msdn.microsoft.com/en-us/library/aa691324(v=vs.71).aspx

Например, в Пролог новых операторов и их приоритеты оценки могут быть добавлены к языку на лету, используя op(Precedence,Type,Name) директиву. Анализатор Prolog считывает и оценивает ввод строки за строкой. Каждая «строка» завершается .
См http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlse40

0

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

Если вы хотите расширить синтаксис, а не только семантику, вы можете захотеть избавиться от своего лексера и использовать вместо этого синтаксический синтаксический анализ без использования lexerless, а именно: PEGs. Некоторые языки уже делают это (Katahdin, pfront, CLike).