كيفية إصلاح YACC Shift / قم بتقليل النزاعات من مشغل ما بعد الزيادة؟

StackOverflow https://stackoverflow.com/questions/890038

سؤال

أنا أكتب قويما في 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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top