كيفية إصلاح YACC Shift / قم بتقليل النزاعات من مشغل ما بعد الزيادة؟
-
23-08-2019 - |
سؤال
أنا أكتب قويما في YACC (في الواقع بيسون)، وأنا أواجه مشكلة تحول / تقليل. ينتج عن بما في ذلك زيادة بوسفيكس وتناقص المشغلين. فيما يلي نسخة مخفضة من القواعد:
%token NUMBER ID INC DEC
%left '+' '-'
%left '*' '/'
%right PREINC
%left POSTINC
%%
expr: NUMBER
| ID
| expr '+' expr
| expr '-' expr
| expr '*' expr
| expr '/' expr
| INC expr %prec PREINC
| DEC expr %prec PREINC
| expr INC %prec POSTINC
| expr DEC %prec POSTINC
| '(' expr ')'
;
%%
يخبرني BISON أن هناك 12 صراعا تحول / تقليل النزاعات، ولكن إذا قمت بتعليق الخطوط لزيادة بوسفيكس وانخفاض ذلك، فإنه يعمل بشكل جيد. هل يعرف أحد كيفية إصلاح هذا الصراع؟ في هذه المرحلة، أفكر في الانتقال إلى مولد محلل محلل LL (K)، مما يجعله أسهل بكثير، ولكن يبدو أن قواعد النحوية LALR دائما أكثر طبيعية للكتابة. أنا أيضا أفكر في GLR، لكنني لا أعرف أي مولدات محلل GLR جيدة C / C ++.
المحلول
Bison / YACC يمكن أن تولد محلل غاضب إذا حددت %glr-parser
في قسم الخيار.
نصائح أخرى
جرب هذا:
%token NUMBER ID INC DEC
%left '+' '-'
%left '*' '/'
%nonassoc '++' '--'
%left '('
%%
expr: NUMBER
| ID
| expr '+' expr
| expr '-' expr
| expr '*' expr
| expr '/' expr
| '++' expr
| '--' expr
| expr '++'
| expr '--'
| '(' expr ')'
;
%%
المفتاح هو إعلان مشغلي postfix كما غير الإرشادية. وبعد خلاف ذلك سوف تكون قادرة على
++var++--
يجب أيضا إعطاء الأقواس سبأية لتقليل التحذيرات التحول / التقليل
أحب تحديد المزيد من العناصر. يجب أن لا تحتاج إلى اليسار٪،٪ الحق،٪ prise الاشياء.
simple_expr: NUMBER
| INC simple_expr
| DEC simple_expr
| '(' expr ')'
;
term: simple_expr
| term '*' simple_expr
| term '/' simple_expr
;
expr: term
| expr '+' term
| expr '-' term
;
العب مع هذا النهج.
هذه المشكلة الأساسية هي أنه ليس لديك أسبقية ل INC
و DEC
الرموز، لذلك لا يعرف كيفية حل الغموض التي تنطوي على نظرة INC
أو DEC
. وبعد اذا اضفت
%right INC DEC
في نهاية قائمة الأسبقية (تريد أن تكون أياد أعلى من الأسبقية وأعلى postfix أعلى من البادئة)، وسوف تصلحها، ويمكنك حتى التخلص من كل PREINC
/POSTINC
الأشياء، كما انها غير ذات صلة.
عوامل التشغيل Princractrent و postincrement لها NONASSOC لتحدد ذلك في قسم الأسبقية وفي القواعد تجعل الأسبقية من هذه المشغلين عالية باستخدام %prec