игнорировать совпадающую продукцию в yacc

Можно ли при использовании GNU bison ничего не делать после сопоставления продукции, а затем проверить, можно ли использовать какое-либо другое правило для уменьшения той же последовательности токенов? В принципе, то, что я ищу, похоже на это:

iexpr: VARIABLE { if (condition) {
                    /*some action */
                  }
                  else {
                    /*pushback read symbol, and check if other pattern can
                         be matched */
                  }
                }
 fexpr: VARIABLE {   }

Спасибо


person Arani    schedule 24.12.2012    source источник
comment
Мне любопытно узнать, как у вас появилось это требование. Я не знаю о такой возможности с бизоном. Если элемент управления выполняет ваш код, это означает, что bison уже сопоставил шаблон для вас. Даже если вы каким-то образом взломаете его и попытаетесь достичь своей цели, bison в конечном итоге будет соответствовать тому же правилу для следующей итерации. Я бы предложил правильно определить грамматику. Я мог бы помочь вам, если вы скажете, что вы разбираете.   -  person Icarus3    schedule 25.12.2012
comment
@AshishMahamuni: я в основном согласен с вашей оценкой. Я не могу ответить за ОП, но один контекст, в котором что-то подобное может быть полезным, - это подробный язык (SQL), где вы хотите разрешить использование ключевых слов в качестве идентификаторов. Я видел, как вещи были сфальсифицированы таким образом, что при обнаружении ошибки, если токен в настоящее время является ключевым словом, синтаксис повторялся с типом токена IDENTIFIER вместо ключевого слова. Это работает на удивление хорошо; есть еще несколько мест, где у вас могут возникнуть проблемы с этим.   -  person Jonathan Leffler    schedule 25.12.2012
comment
Пожалуйста, исправьте терминологию. Это произведения, а не «шаблоны».   -  person user207421    schedule 25.12.2012
comment
@AshishMahamuni пытаюсь создать интерпретатор со строгой типизацией. Таким образом, целочисленные выражения (iexpr) и выражения с плавающей запятой (fexpr) могут быть получены из переменных в зависимости от типа переменной.   -  person Arani    schedule 25.12.2012
comment
@EJP исправлено. Спасибо, что указали на это   -  person Arani    schedule 25.12.2012
comment
Вы не можете выразить тип в грамматике, и вам не следует пытаться. Грамматика предназначена только для синтаксиса. Проект Алгол-68 был последней попыткой ввода грамматики, и он закончился знаменитым фиаско.   -  person user207421    schedule 25.12.2012
comment
@EJP Итак, что вы предлагаете для строго типизированного языка?   -  person Arani    schedule 25.12.2012
comment
реентерабельный парсер решит проблему. см. phpcompiler.org/articles/reentrantparser.html   -  person Icarus3    schedule 25.12.2012


Ответы (2)


Что ж, вы можете сделать это с помощью btyacc — варианта yacc, который выполняет возврат:

iexpr: VARIABLE [ if (!condition)
                     /* this parse was wrong, backtrack and try something else */
                    YYERROR; ]
                { /* some action */ }
fexpr: VARIABLE { /* some other action */  }

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

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

expr: expr '+' expr {
    Typecheck('+', $1, $3); /* make sure operand types are appropriate for an add */
    $$ = BuildBinopCode('+', $1, $2); /* build some code to add two things */
}
person Chris Dodd    schedule 25.12.2012

Для этого вы должны иметь возможность использовать функцию YYBACKUP.

person user207421    schedule 25.12.2012
comment
как? пример? - person quetzalfir; 02.12.2018