2012-06-14 2 views
0

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

uses ConsoleIO 

r(int)success start (int) nArgument 
    printHelloWorlds 
    return 0 

printHelloWorld 
    print "Hello world\n" 

printHelloWorlds 
    getNumberFrom 4 into timesToPrint 
    timesPrinted = 0 
    printHelloWorld 
    timesPrinted = timesPrinted + 1 
    if timesPrinted < timesToPrint 
     goToLine 17 

getNumberFrom (int)number into o(int) out 
    name = "John" 
    out = 3 + name.findFirstOccurenceOf 'o' + number 

r(int) (string)str .findFirstOccurenceOf (char)c 
    //later 
    return 3 

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

  • положить г перед переменной делает его возвращаемое значение
  • переменные «объявлены» только путем ссылки
  • Имя функции не может содержать два последовательных «имя лексемы», должен быть хотя бы один аргумент между каждым токеном имени (и, возможно, для нескольких переменных потребуются запятые между ними, хотя я бы предпочел не требовать, чтобы, если я могу управлять разбором без этого ограничения)
  • положить o перед переменная делает его «выходным» значением. В этом случае функция должна записывать в нее перед чтением, и переменная не должна существовать до вызова функции (на «getNumberFrom 4 to timesToPrint» timesToPrint не существует до создания, когда getNumberFrom (int) в o (целый) называются

Я уже запрограммировал лексер к:

  • Интерпретировать объявления функций, иметь дело с областью, обрабатывать литералы и т.д.
  • Читайте в обычных строках коды и сделать список каждого токена, а также список всех функций, которые содержат каждый токен в их имени (если есть), распознают, является ли токен именем переменного
  • Я не имею дело с управлением потоком (если/Goto) все же, в настоящее время они рассматриваются как обычные функции

Однако, теперь мне нужно на самом деле выяснить, какие функции (s) каждая строка вызывает, в каком порядке и с каким входом, а также с выводами (переменными o), и я ударил немного дорожного блока. У меня нет опыта в этом, и я не уверен, с чего начать. Я знаю, что мне понадобится какая-то рекурсивная функция.

В принципе, может ли кто-нибудь сказать мне, какой тип алгоритма я ищу, или, может быть, просто несколько слов, чтобы начать поиск в Google, чтобы узнать больше? Должен ли я использовать бизон или antlr или что-то еще, или это язык, который этот гибкий/странный будет слишком сложным для этого?

Примечание: Я не использую Bison или Flex или что-нибудь, я пишу весь код сам в C++

ответ

1

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

bison поддерживает парные анализаторы снизу вверх в семействе LR: LALR (1), LR (1), GLR (1) и новые алгоритмы IELR (1). Они захватывают большое количество языков, но вам нужно немного узнать об алгоритме синтаксического анализа, чтобы исправить некоторые из ошибок, которые могут возникнуть (а именно, сдвиг/уменьшение и уменьшение/уменьшение).

ANTLR использует LL (*) парсеры, которые захватывают немного меньший набор языков, но имеют тенденцию работать красиво на многих языках программирования.

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

Если вы настаиваете на сворачивании собственного анализатора, вы можете фактически реализовать вышеперечисленные алгоритмы вручную, но это чрезвычайно сложно. Самый простой вариант - использовать парсер с наименьшим рекурсивным спусками с обратным отсчетом или дребезжать грамматику до тех пор, пока она не станет LL (1), а затем используйте простой синтаксический анализатор без обратного отслеживания. Тем не менее, я думаю, вы делаете вещи намного сложнее, чем они должны быть.

Надеюсь, это поможет!

+0

+1 для справки IELR. Всегда хорошо, когда старая собака узнает новые трюки. –

+0

После того, как вы сделали много поисковых запросов о Bison, ANTRl, LL (*) Parsers и т. Д., Кажется, что все они работают над безконкурентными грамматиками, и я вполне уверен, что мой язык не является контекстуальным, хотя я не совершенно уверен, поскольку я все еще работаю над расшифровкой всех этих страниц в википедии .... – zacaj

+0

@ zacaj- Большинство языков программирования не являются контекстно-свободными, но их можно рассматривать как контекстно-свободный язык с некоторыми дополнительными ограничениями, представляющими такие как область видимости и т. д. Язык, который вы описали, безусловно, выглядит достаточно контекстно-зависимым, чтобы анализировать эти алгоритмы. – templatetypedef

Смежные вопросы