Compiler construction 野牛减少/减少冲突(如果有其他情况)

Compiler construction 野牛减少/减少冲突(如果有其他情况),compiler-construction,bison,Compiler Construction,Bison,我本来希望if-else使用shift/reduce-conlict,但它在“if”(“boolean_语句”)行上给出了reduce/reduce冲突块 以下是一些可能有助于解释以下代码的信息: BOOL是每行开头使用的关键字的标记,表示行是布尔运算 布尔值为“真”或“假”值 我正在使用这个编译器将一种语言转换成C代码,这种语言可以包含像a,b,C=d+2这样的语句,这相当于C中的a=b=C=d+2;和boole=f*.N。g+h,相当于e=f&&!g | | h statements:

我本来希望if-else使用shift/reduce-conlict,但它在“if”(“boolean_语句”)行上给出了reduce/reduce冲突块

以下是一些可能有助于解释以下代码的信息:

  • BOOL
    是每行开头使用的关键字的标记,表示行是布尔运算

  • 布尔值
    为“真”或“假”值

  • 我正在使用这个编译器将一种语言转换成C代码,这种语言可以包含像
    a,b,C=d+2
    这样的语句,这相当于C中的
    a=b=C=d+2
    ;和
    boole=f*.N。g+h
    ,相当于
    e=f&&!g | | h

    statements:
            statements statement
            | statement
            ;
    
    statement:
            if_statement
            | BOOL variable_list '=' boolean_statement
            | variable_list '=' integer_statement
            ;
    
    if_statement:
            IF '(' boolean_statement ')' block ELSE block
            | IF '(' boolean_statement ')' block
            ;
    
    variable_list:
            variable_list ',' variable
            | variable
            ;
    
    variable:
            STRING 
            | STRING '[' INTEGER ']'
            | STRING '[' STRING ']'
            ;
    
    boolean_statement:
            '(' boolean_statement ')'
            | bval '*' boolean_statement
            | bval '+' boolean_statement
            | bval EQ boolean_statement
            | bval NEQ boolean_statement
            | NOT boolean_statement
            | bval
            ;
    
    bval:
            BOOLEAN   
            | variable
            ;
    
    integer_statement:
            '(' integer_statement ')'
            | value '+' integer_statement
            | value '*' integer_statement
            | value
            ;
    
    value:
            INTEGER        
            | variable
            ;
    
    block:
            statement
            | '{' statements '}'
            ;
    
这是完整的代码

   %{

    #include <cstdio>
    #include <iostream>
    using namespace std;

    //stuff from flex that bison needs to know about:
    extern "C" int yylex();
    extern "C" int yyparse();
    extern "C" FILE *yyin;
    extern int line_num;

    void yyerror(const char *s);

    %}

    //C union holding each of the types of tokens that Flex could return
    %union { 
            int ival;
            bool bval;
            char const *sval;
    }

    //symbol defination
    %token <sval> STRING;
    %token <sval> NOT
    %token CONSTANT_SECTION
    %token BOOLEAN_SECTION
    %token INTEGER_SECTION
    %token LOGIC_SECTION
    %token TIMER_SECTION
    %token <sval> BOOLEAN
    %token <ival> INTEGER
    %token <ival> HEX 
    %token ENDL 
    %token BOOL
    %token IF
    %token ELSE
    %token EQ NEQ
    %token AND
    %token OR
    %token SUBROUTINE_END
    %token SUBROUTINE_START
    %token DELAY SECONDS HOURS MINUTES MSEC
    %token GOTO
    %token LABEL
    %token CALL
    //end of declaration section
    %%

    logic:
            costants_declarations boolean_declarations integer_declarations timer_declarations logic_statements
            | boolean_declarations integer_declarations timer_declarations logic_statements
            | logic_statements
            ;

    costants_declarations:
            CONSTANT_SECTION constants  
            ;

    constants:
            constants STRING '=' INTEGER    { cout << "const int " << $2 << " = "  << $4 << ";" << endl; }
            | constants STRING '=' HEX      { cout << "const int " << $2 << " = "  << $4 << ";" << endl; }
            | STRING '=' INTEGER            { cout << "const int " << $1 << " = "  << $3 << ";" << endl; }
            | STRING '=' HEX                { cout << "const int " << $1 << " = "  << $3 << ";" << endl; }
            ;

    boolean_declarations:
            BOOLEAN_SECTION booleans       
            ;

    booleans:
            booleans ',' boolean             
            | booleans boolean               
            | boolean                       
            ;        

    boolean:
            STRING '[' INTEGER ']'          { cout << "bool " << $1 << "[" << $3 << "]" << ";" << endl; }
            | STRING '[' STRING ']'         { cout << "bool " << $1 << "[" << $3 << "]" << ";" << endl; }
            | STRING                        { cout << "bool " << $1 << " = true;" << endl; }
            ;

    integer_declarations:
            INTEGER_SECTION integers
            ;

    integers:
            integers ',' integer            
            | integers integer              
            | integer                      
            ;

    integer:
            STRING '[' INTEGER ']'          { cout << "int " << $1 << "[" << $3 << "]" << ";" << endl; }
            | STRING '[' STRING ']'         { cout << "int " << $1 << "[" << $3 << "]" << ";" << endl; }
            | STRING                        { cout << "int " << $1 << " = 0;" << endl; }
            ;

    timer_declarations:
            TIMER_SECTION timers
            ;

    timers:
            timers ',' timer
            | timers timer
            | timer
            ;

    timer:
            STRING                          { cout << "int " << $1 << ";" << endl; }
            ;

    logic_statements:
            LOGIC_SECTION subroutines statements
            ;

    subroutines:
            /* empty */
            | SUBROUTINE_START STRING statements SUBROUTINE_END STRING
            ;

    statements:
            statements statement
            | statement
            ;

    statement:
            if_statement
            | delay_statement
            | GOTO STRING
            | LABEL
            | CALL STRING
            | BOOL variable_list '=' { cout << " = "; } boolean_statement { cout << ";\n"; } 
            | variable_list '=' { cout << " = "; } integer_statement { cout << ";\n"; }
            ;

    if_statement:
            IF '(' { cout << "if("; } boolean_statement ')' { cout << ")" << endl; } block
            | IF '(' { cout << "if("; } boolean_statement ')' { cout << ")" << endl; } block ELSE block
            ;

    delay_statement:
            DELAY '=' INTEGER SECONDS statement 
            ;

    variable_list:
            variable_list ',' { cout << " = "; } variable
            | variable
            ;

    variable:
            STRING                          { cout << $1; }
            | STRING '[' INTEGER ']'        { cout << $1 << "[" << $3 << "]"; }
            | STRING '[' STRING ']'         { cout << $1 << "[" << $3 << "]"; }
            ;

    boolean_statement:
            '('{ cout << "("; } boolean_statement ')'{ cout << ")"; }
            | bval '+' { cout << " || "; } boolean_statement
            | bval OR { cout << " || "; } boolean_statement
            | bval '*' { cout << " && "; } boolean_statement
            | bval AND { cout << " && "; } boolean_statement
            | bval EQ { cout << " == "; } boolean_statement
            | bval NEQ { cout << " != "; } boolean_statement
            | NOT { cout << $1; } boolean_statement
            | bval
            ;

    bval:
            BOOLEAN                          { cout << $1; }
            | variable
            ;

    integer_statement:
            '('{ cout << "("; } integer_statement ')'{ cout << ")"; }
            | value '+'{ cout << " + "; } integer_statement
            | value '*'{ cout << " * "; } integer_statement
            | value
            ;

    value:
            INTEGER                       { cout << $1; }
            | variable
            ;

    block:
            { cout << "{" << endl; } statement { cout << "}" << endl; }
            | '{' { cout << "{" << endl; } statements '}' { cout << "}" << endl; }
            ;

    //end of grammer section
    %%

    int main(int argc, char *argv[]) {

            // default input is stdin
            // if file is given read from it
            if(argc == 2)
            {
                    // open a file handle to a particular file:
                    FILE *myfile = fopen(argv[1], "r");
                    // make sure it's valid:
                    if (!myfile) {
                            cout << "Can't open "<< argv[1] <<" file" << endl;
                            cout << "Usage: " << argv[0] << " <filename>\n";
                            return -1;
                    }
                    // set lex to read from it instead of defaulting to STDIN:
                    yyin = myfile;
            }
            else if(argc != 1)
            {
                    cout << "Usage: " << argv[0] << " <filename>\n";
                    cout << "Usage: " << argv[0] << endl;
                    return -1;
            }

            // parse through the input until there is no more:
            do 
            {
                    yyparse();
            } while (!feof(yyin));
    }

    void yyerror(const char *s) {
        cout << "Parse error on line " << line_num << "!  Message: " << s << endl;
        // might as well halt now:
        exit(-1);
    }
%{
#包括
#包括
使用名称空间std;
//bison需要了解的flex中的内容:
外部“C”int yylex();
外部“C”int yyparse();
外部“C”文件*yyin;
外部内部行数;
无效错误(常量字符*s);
%}
//C union持有Flex可以返回的每种类型的令牌
%联合{
国际竞争力;
布尔布尔;
char const*sval;
}
//符号定义
%令牌串;
%代币不是
%令牌常数部分
%令牌布尔单元
%令牌整数部分
%令牌逻辑单元
%令牌定时器单元
%标记布尔
%令牌整数
%符号十六进制
%令牌端
%令牌布尔
%代币如果
%其他代币
%令牌均衡NEQ
%代币和
%象征或
%令牌子程序
%令牌子程序启动
%令牌延迟秒小时分钟毫秒
%代币转投
%令牌标签
%令牌呼叫
//申报部分结束
%%
逻辑:
costants_声明布尔_声明整数_声明计时器_声明逻辑_声明
|布尔\u声明整数\u声明计时器\u声明逻辑\u语句
|逻辑逻辑语句
;
共同费用声明:
常数\截面常数
;
常数:

常量字符串“=”整数{cout问题不完全在于
IF
语句。问题在于
IF\u语句的两个产品中的中间规则操作(MRA):

if_statement:
          IF '(' { cout << "if("; } boolean_statement ')' { cout << ")" << endl; } block
        | IF '(' { cout << "if("; } boolean_statement ')' { cout << ")" << endl; } block ELSE block
        ;

如果切换If定义的顺序(请在一秒钟内执行ELSE),那么您是否得到了shift/reduce错误?@MichaelWelch我仍然得到了错误,但是无论这两个语句的顺序如何,reduce/reduce都是错误的。@Ruturaj:请显示您的整个bison输入,包括
%
定义,并确保您正在复制精确的文件。由于未加引号,您当前的文件会引发bison语法错误<代码>+
*
布尔_语句
规则中。一旦我解决了这个问题,bison只给了我预期的shift/reduce冲突,所以我断定您实际使用的文件是不同的。@rici我在前面问题的末尾添加了我的全部代码。很抱歉,该语言使用了两种类型的and/or符号,*/+或&/| |。这就是为什么我删除了一些垃圾,忘记添加引号的原因。@Ruturaj:谢谢,这样回答起来容易多了。
if_statement:
          IF '(' @3 boolean_statement ')' @4 block
        | IF '(' @5 boolean_statement ')' @6 block ELSE block
        ;

@3: %empty { cout << "if("; }        ;
@4: %empty { cout << ")" << endl; }  ;
@5: %empty { cout << "if("; }        ;
@6: %empty { cout << ")" << endl; }  ;
if_statement:
      if_then
    | if_then ELSE block
    ;

if_then:
      IF '('                   { cout << "if("; }
      boolean_statement ')'    { cout << ")" << endl; }
      block
    ;