2013-12-08 2 views
0

Я писал L интерпретатор LOLCODE и столкнулся с проблемой. В LOLCODE вызовы функции выглядит следующим образом:Bison fix глубина анализа

<func_name> <arg1> <arg2> .... 
myfunc 1 2 3 

Будем считать, что MyFunc взять три арг. я не знаю, как поддержать такую ​​конструкцию:

VISIBLE myfunc 1 2 3 4 

Я хочу зубр, чтобы разобрать его так:

myfunc 1 2 3 -> function 
4 -> expr 

Я объявил вызов функции как:

ID expr_list { $$ = new ExprFunctionCall($1, $2); } 

где expr_list является:

expr_list 
    : expr_list expr { $$->putExpr($2); } 
    | /* epsilon */ { $$ = new ExprList(); } 
    ; 

Как я могу сказать бизону, где остановиться, если я знаю объявленную функциональность?

ответ

3

Вы не можете сделать это в бизоне. Не все равно. Bison - инструмент для анализа контекстно-свободных языков, а ваш зависит от контекста.

Иногда вы можете сгибать правила и заставлять там какую-либо зависимость от контекста, как в случае с C и C++, но в вашем случае, вероятно, стоит исследовать другие генераторы синтаксического анализатора. Если вы все равно хотите это сделать, введите явный токен, чтобы завершить вызов функции, и еще один вспомогательный символ для обработки аргумента функции. Этот специальный токен не является чем-то найденным в источнике, он вводится лексером по запросу анализатора.

Правила должны выглядеть примерно как это (непроверенные, грамматика, скорее всего, не работать с первой попытки, но общая идея такова):

call 
    : function expr_list { ... } 
    ; 

function 
    : ID { ... push function arity on some stack somewhere } 

expr_list 
    : expr_list pre_expr expr { ... } 
    | pre_expr END_LIST { ... } 
    ; 

pre_expr 
    : /* epsilon */ { ... decrease function arity on the top of the stack 
          if it's zero, 
            tell the lexer to issue END_LIST token next 
            and pop the arity off the stack 
        } 
    ; 
Смежные вопросы