игнорирайте съвпадащата продукция в 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: По принцип съм съгласен с оценката ви. Не мога да отговоря за OP, но един контекст, в който нещо подобно може да е полезно, е в подробен език (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
Не можете да изразите тип в граматика и не трябва да опитвате. Граматиката е само за синтаксиса. Проектът Algol-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