2015-05-02 2 views
0

Я пишу компилятор для моего игрушечного языка только для обучения и любопытства, и я уже выполнил некоторые вещи, такие как математические операции и прочее, у меня возникают некоторые проблемы с попыткой проанализировать переменную "внутри «переменная, хотя. Возьмите эти примеры в псевдо-коде:Проанализируйте переменную (рекурсивно)

numbers = [1..20] 

Мой парсер уже это понимают, и такие вещи, как:

ten = numbers[9] 

Однако, когда у меня есть переменная, которая состоит из более чем одного «элемента», как 2D-массив или объект внутри объекта, я не могу разобрать, парсер блокирует себя внутри бесконечного цикла. Пример:

things = [['one'], ['two'], ['three']] 
person = { 
    name = 'john' 
    car = { 
    model = 'ninja' 
    price = 23000.0 
    } 
} 

things[1][0] // This is causing the infinite loop 
person.car.price // And this 

Это то, что мой анализатор выглядит (в псевдокоде):

parseVarReference() { 
    variable = expect(TOKEN_IDENTIFIER); 
    if (current() == '[') { 
    // try to parse array or object or fallback to regular variables 
    } 
} 

Теперь в моей голове, я бы разобрать вложенную переменную так:

parseVarReference() { 
    variable = parseVarReference(); 
    if (current() == '[') { 
    // try to parse array or object or fallback to regular variables 
    } 
} 

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

+1

Я не вижу никакого намека на грамматику, просто какой-то синтаксический код. Ваша жизнь будет намного проще, если вы сначала напишите официальную грамматику для своего языка. Обычно с такой грамматикой вы можете легко закодировать рекурсивный парсер спуска (см. Мой комментарий к ответу Коминека) или использовать генератор парсера. –

+0

Вы не разбираете переменные здесь, вы анализируете первичное выражение. – EJP

ответ

2

Вы пишете recursive descent parser. Они не могут напрямую обрабатывать left recursion.

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

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

+3

Они могут обрабатывать левую рекурсию после преобразования ее на итерацию. См. Этот ответ о том, как написать рекурсивный парсер спуска: http://stackoverflow.com/questions/2245962/is-there-an-alternative-for-flex-bison-that-is-usable-on-8-bit- Встраиваемые системы/2336769 # 2336769 –

+0

Существует также способ обработки левой рекурсии при анализе рекурсивного спуска с помощью memoisation: http://www.vpri.org/pdf/tr2007002_packrat.pdf –

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