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