我有一个语法,根据作品的顺序,快乐的报告3减少/减少冲突或没有.我能找到的最小例子是:
%tokentype {Token}
%token
int { Int }
'-' { Neg }
both { Both }
%nonassoc both
%left '-'
%nonassoc NEG
%%
E : int {IntE}
| both E E {BothE $2 $3}
| '-' E %prec NEG {NegE $2}
| E '-' E {SubE $1 $3}
{
data Token = Int | Neg | Both deriving Show
data Expr = BothE Expr Expr | IntE | SubE Expr Expr | NegE Expr deriving Show
}
Run Code Online (Sandbox Code Playgroud)
这有3个减少 - 减少冲突,基于无法区分" …
我很难绕过这个并且需要一些帮助来理解转移减少并减少冲突.我有一个语法,我似乎无法理解为什么它有问题.我可以附上语法,但我想知道这是如何工作的.
第一个问题,MGrammer创建了什么类型的解析器?据我了解,shift reduce和reduce reduce冲突取决于解析器的类型.
第二个问题,什么意味着减少减少冲突和什么意味着转移减少冲突?
我知道词法分析和正式语法的基础知识,但是自从我使用语言设计以来已经有一段时间了,所以这里的任何帮助都是非常合适的.
我正在使用一种空白重要的语言,我想知道在MGrammar中这样做的可能性,我是否需要看一眼才能解决歧义?
我是 Bison 解析的新手,我无法理解它是如何工作的。我有以下语法,其中我保留了最低限度的语法来突出问题。
%left '~'
%left '+'
%token T_VARIABLE
%%
start: expr;
expr: composite_expr | variable_expr;
variable_expr: T_VARIABLE;
composite_expr:
expr '+' expr
| '~' variable_expr { do_something_1(); }
| '~' composite_expr { do_something_2(); }
;
%%
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我想'~'
根据后面的表达式类型对运算符应用不同的函数。然而,这会产生2个reduce/reduce冲突。
当然,如果我像这样重写composite_expr规则......
composite_expr:
expr '+' expr
| '~' expr { /* ??? */ }
;
Run Code Online (Sandbox Code Playgroud)
...然后就没有冲突了,但现在我不能调用 or ,do_something_1()
因为do_something_2()
我无法再判断expr
isvariable_expr
或composite_expr
。
还有其他方法可以做到这一点吗?谁能解释为什么首先要减少/减少冲突?
请记住,这是一个精简版本,实际上,规则composite_expr
很长。所以复制它是不可能的。
为什么这会引发关于减少/减少冲突的警告
root : set1 'X'
| set2 'X' 'X'
set1 : 'A'
| 'B'
set2 : 'B'
| 'C'
Run Code Online (Sandbox Code Playgroud)
但接下来还可以吗?
root : 'A' 'X'
| 'B' 'X'
| 'B' 'X' 'X'
| 'C' 'X' 'X'
Run Code Online (Sandbox Code Playgroud) 以下解析逻辑表达式的简单语法会导致减少/减少冲突:
%token AND OR
%token NUMBER VARIABLE
%%
logical_expr
: logical_expr AND logical_term
| logical_expr OR logical_term
| logical_term
;
logical_term
: VARIABLE
| comparison
| '(' logical_expr ')'
;
comparison
: expr '<' expr
| expr '>' expr
;
expr
: expr '+' term
| expr '-' term
| term
;
term
: NUMBER
| VARIABLE
| '(' expr ')'
;
%%
Run Code Online (Sandbox Code Playgroud)
野牛的状态报告有:
state 2
4 logical_term: VARIABLE .
13 term: VARIABLE .
')' reduce using rule 4 (logical_term) …
Run Code Online (Sandbox Code Playgroud) 用我的语言我可以写
a = 1
b = 2
if true { } else { }
if true { } **Here is the problem**
else {}
Run Code Online (Sandbox Code Playgroud)
我的语法不支持语句之间的换行符.else只能与if一起使用.当我在我的规则中添加optionalNL时
IfExpr:
IF rval optionalNL codeBlock optionalNL ELSE codeBlock
| IF rval optionalNL codeBlock
Run Code Online (Sandbox Code Playgroud)
在else之前的optionalNL导致3减少/减少.原因是它可以减少使用IfExpr中的第二个规则或者减少到exprLoop,它允许表达式之间有许多换行符.
无论我做什么(我尝试在OptionalNL和ELSE之前编写%prec)它总是减少到exprLoop,哪些情况下bison给我一个关于else的synax错误.我怎么告诉野牛在这一点上转移(到OptionalNL其他)而不是减少?(exprLoop导致else成为错误).
用于测试的示例文件
%%
program:
exprLoop;
exprLoop:
exprLoop2 expr
| exprLoop2
exprLoop2:
| exprLoop2 expr EOS
| exprLoop2 EOS
;
expr:
'i' Var optEOS '{' '}'
| 'i' Var optEOS '{' '}' optEOS 'e' '{' '}'
EOS: '\n' ;
Var: 'v';
optEOS: …
Run Code Online (Sandbox Code Playgroud)