2017-10-22 10 views
0

ルールの途中でコード{printf( "something");}を置くとこの警告が表示されます。ルールの終わり、私はエラーがなく、すべてうまく動作します。

この点画に警告を投げると1つのシフトを投げる/ reduce衝突

sent_asig: ID {printf("something");} ASIG exp {printf("sent_asig: ID ASIG exp \n");} 
| ID ASIG CTE_STRING {printf("sent_asig: ID ASIG CTE_STRING \n");} 
| ID ASIG CTE_STRING CONCAT ID {printf("sent_asig: ID ASIG CTE_STRING CONCAT ID \n");} 
| ID ASIG ID CONCAT CTE_STRING {printf("sent_asig: ID ASIG ID CONCAT CTE_STRING \n");}; 

そして、これは誰かがしたい場合は罰金

sent_asig: ID ASIG exp {printf("sent_asig: ID ASIG exp \n");} 
| ID ASIG CTE_STRING {printf("sent_asig: ID ASIG CTE_STRING \n");} 
| ID ASIG CTE_STRING CONCAT ID {printf("sent_asig: ID ASIG CTE_STRING CONCAT ID \n");} 
| ID ASIG ID CONCAT CTE_STRING {printf("sent_asig: ID ASIG ID CONCAT CTE_STRING \n");}; 

を働き、警告と0競合をスローすることはありませんこのエラーの原因が他の部分にある可能性があるので、完全なルールを参照してください。

%token ID 
%token CTE 
%token ABREPAR 
%token FINPAREN 
%token AND 
%token OR 
%token COMA 
%token ASIG 
%token COMP 
%token RESTASIG 
%token CONCAT 
%token SUMASIG 
%token MULTASIG 
%token DIVASIG 
%token MENOR_IGU 
%token MENOR 
%token MAYOR_IGU 
%token MAYOR 
%token NOT 
%token DIST 
%token CTE_REAL 
%token CTE_STRING 

%token DO 
%token IF 
%token ENDIF 
%token ELSE 
%token PUT 
%token GET 
%token DECLARE 
%token ENDDECLARE 
%token BEGIN 
%token ENDPROGRAM 
%token INT 
%token REAL 
%token STRING 
%token REPEAT 
%token CONST 

%left AND OR 
%left OP_SUM OP_RESTA 
%left OP_MULT 
%left OP_DIV 
%right ASIG 
%right SUMASIG 
%right RESTASIG 
%right MULTASIG 
%right DIVASIG 

%% 

programa: BEGIN declar sentencias ENDPROGRAM {printf("programa: BEGIN declar sentencias ENDPROGRAM \n");} 
| BEGIN sentencias ENDPROGRAM {printf("programa: BEGIN sentencias ENDPROGRAM \n");}; 

sentencias: sentencia {printf("sentencia: sentencia \n");} 
    | sentencias sentencia {printf("sentencias: sentencia \n");}; 
sentencia: sent_asig {printf("sentencia: sent_asig\n");} 
    | sent_mult_asig {printf("sentencia: sent_mult_asig\n");} 
    | sent_sum_asig {printf("sentencia: sent_sum_asig");} 
    | sent_rest_asig {printf("sentencia: sent_rest_asig \n");} 
    | sent_div_asig {printf("sentencia: sent_div_asig \n");} 
    | asig_const {printf("sentencia: asig_const \n");} 
    | entrada {printf("sentencia: entrada \n");} 
    | salida {printf("sentencia: salida \n");} 
    | sent_if {printf("sentencia: sent_if \n");} 
    | sent_repeat {printf("sentencia: sent_repeat \n");}; 
sent_asig: ID {printf("something");} ASIG exp {printf("sent_asig: ID ASIG exp \n");} 
    | ID ASIG CTE_STRING {printf("sent_asig: ID ASIG CTE_STRING \n");} 
    | ID ASIG CTE_STRING CONCAT ID {printf("sent_asig: ID ASIG CTE_STRING CONCAT ID \n");} 
    | ID ASIG ID CONCAT CTE_STRING {printf("sent_asig: ID ASIG ID CONCAT CTE_STRING \n");}; 
exp:  exp OP_SUM ter {printf("exp: exp OP_SUM ter\n");escribirPolaca("+");} 
    | exp OP_RESTA ter {printf("exp: exp OP_RESTA ter\n");escribirPolaca("-");} 
    | ter {printf("exp: ter\n");}; 

ter: ter OP_MULT factor {printf("ter: ter OP_MULT factor\n");escribirPolaca("*");} 
    | ter OP_DIV factor {printf("ter: ter OP_DIV factor\n");escribirPolaca("/");} 
    | factor {printf("ter: factor\n");}; 
factor: ID {printf("factor: ID\n"); escribirPolaca(Simbolos[nosalemal][0]);} 
    | CTE {printf("factor: CTE\n");escribirPolaca(Simbolos[nosalemal][1]);} 
    | CTE_REAL {printf("factor: CTE_REAL \n");escribirPolaca("CTE_REAL");}; 
    | ABREPAR exp FINPAREN {printf("factor: ABREPAR exp FINPAREN\n");} 
sent_sum_asig : ID SUMASIG ID {printf("factor: sent_sum_asig \n");} 
    | ID SUMASIG CTE {printf("factor: ID SUMASIG CTE \n");} 
    | ID SUMASIG CTE_REAL {printf("factor: ID SUMASIG CTE_REAL \n");} ; 
sent_rest_asig : ID RESTASIG ID {printf("sent_rest_asig: ID RESTASIG ID \n");} 
    | ID RESTASIG CTE {printf("sent_rest_asig: ID RESTASIG CTE \n");} 
    | ID RESTASIG CTE_REAL {printf("sent_rest_asig: ID RESTASIG CTE_REAL \n");}; 
sent_mult_asig : ID MULTASIG ID {printf("sent_mult_asig: ID MULTASIG ID \n");} 
    | ID MULTASIG CTE {printf("sent_mult_asig: ID MULTASIG CTE \n");} 
    | ID MULTASIG CTE_REAL {printf("sent_mult_asig: ID MULTASIG CTE_REAL \n");}; 
sent_div_asig : ID DIVASIG ID {printf("sent_div_asig: ID DIVASIG ID \n");} 
    | ID DIVASIG CTE {printf("sent_div_asig : ID DIVASIG ID \n");} 
    | ID DIVASIG CTE_REAL {printf("sent_div_asig: ID DIVASIG ID \n");}; 
declar: DECLARE declaraciones ENDDECLARE {printf("declar: DECLARE declaraciones ENDDECLARE \n");}; 
declaraciones: dec {printf("declaraciones: dec \n");} 
    | dec declaraciones {printf("declaraciones: dec declaraciones \n");}; 
dec: REAL var {printf("dec: REAL var \n");} 
    | INT var {printf("dec: INT var \n");} 
    | STRING var {printf("dec: STRING var \n");} ; 
var: ID {printf("var: ID \n");} 
    | ID COMA var {printf("var: ID COMA var \n");}; 
asig_const: CONST ID ASIG CTE {printf("asig_const: CONST ID ASIG CTE \n");} 
    | CONST ID ASIG CTE_REAL {printf("asig_const: CONST ID ASIG CTE_REAL \n");} 
    | CONST ID ASIG CTE_STRING {printf("asig_const: CONST ID ASIG CTE_STRING \n");}; 
entrada: PUT CTE_STRING {printf("entrada: PUT CTE_STRING \n");} 
    | PUT ID {printf("entrada: PUT ID \n");}; 
salida: GET ID {printf("salida: GET ID \n");}; 
sent_if: IF ABREPAR condicion FINPAREN sentencias ENDIF {printf("sent_if: IF ABREPAR condicion FINPAREN sentencias ENDIF \n");} 
    | IF ABREPAR condicion FINPAREN sentencias ELSE sentencias ENDIF {printf("sent_if: IF ABREPAR condicion FINPAREN sentencias ELSE sentencias ENDIF \n");} 
condicion: cond {printf("condicion: cond \n");} 
    | cond AND cond {printf("condicion: cond AND cond\n");} 
    | cond OR cond {printf("condicion: cond OR cond \n");} 
    | NOT cond {printf("condicion: NOT cond \n");}; 
cond: exp MENOR exp {printf("cond: exp MENOR exp \n");apilarPilaIteracion(posicionVectorPolaca);escribirPolaca("CMP");posicionVectorPolaca++;} 
    | exp MAYOR exp {printf("cond: exp MENOR exp \n");} 
    | exp MENOR_IGU exp {printf("cond: exp MENOR exp \n");} 
    | exp MAYOR_IGU exp {printf("cond: exp MENOR exp \n");} 
    | exp COMP exp {printf("cond: exp MENOR exp \n");escribirPolaca("CMP");} 
    | exp DIST exp {printf("cond: exp MENOR exp \n");} 
sent_repeat: DO sentencias REPEAT ABREPAR condicion FINPAREN {printf("sent_repeat: DO sentencias REPEAT ABREPAR condicion FINPAREN \n");}; 
%% 

申し訳ありませんが私の悪い英語(スペイン語で答えることができれば、より良い)

答えて

1

この状況はbison manualで説明されています。基本的に、ミッド・ルール・アクション(MRA)、つまりルールの途中のアクションを使用すると、パーサーがルールの終わりまで削減判断を延期する能力が低下します。実際には、構文解析のその時点で、文法はあたかもLL(1)文法のように予測可能でなければならない。このため、MRAは厳密に必要な場合にのみ使用してください。具体的には

、ちょうど次の二つの選択肢(切り捨て)を検討:

sent_asig: ID {printf("something");} ASIG exp … 
     | ID ASIG CTE_STRING … 

を、パーサはちょうどIDを認識し、入力ストリームの次のトークンがASIGであると仮定します。この時点で、パーサーはMRA { printf("something"); }を実行するかどうかを決定する必要があります。その背後では、MRAを実行することは、非終端記号(右辺が空である端末)を減らすことと同じであるため、パーサーは縮小を実行するかどうかを決定する必要があります。しかし、まだ十分な情報がありません。 の後にASIGのトークンがCTE_STRINGであるかどうかを見るまでは、この決定はできません。したがって、解決には2つの先読みトークンが必要です。シフトだ

は/競合を減らす:パーサは(MRAを実行する)マーカーを減らすASIGシフトするかどうかを決定することはできません。 bison/yaccパーサーは常にシフトによってシフト/縮小の競合を解決するため、この減少は決して起こりません。 MRAは実行できず、MRAを含む右側が効果的にブロックされます。したがって警告。あなたは、両方のポイントで同じMRAを挿入することによって、問題を解決することはできません

注:

のMRAが同一であるにもかかわらず、バイソン/ yaccが作成することになり2つのルールの異なるマーカーを、挿入
sent_asig: ID {printf("something");} ASIG exp … 
     | ID {printf("something");} ASIG CTE_STRING … 

削減/削減競合。縮小/縮小の競合は、入力ファイルの前に表示される縮小を選択することで解決されます。解像度はファイルのデフォルトの解像度とは異なりますが、1つ(または複数)の規則はブロックされますが、警告。あなただけのパーサーが何をしているかを確認するためにしようとしている場合


、私は強くあなたがそれらのprintfをのすべてを削除し、使用可能にすることが非常に簡単である、bison's built-in trace facilityに代わりに頼って(または無効)ことを示唆している、とされ解析がどのように進行しているかをより完全に把握できます。

関連する問題