Bison 的右递归规则问题
Problem with right recursive rules with Bison
我用bison实现了多维数组的管理
这段代码有效,使用左递归规则
然而。说明书上说最好用右边的。 link : Bison Recursive Rules
但是,现在,如果我使用正确的规则,数组将不会被正确解析。
问题是,当我使用正确的规则时,内部数组 a[2,3] returns 是 4 个维度而不是 2 个维度,而另一个数组 x[] 没有维度。
我的问题是:为什么这段代码不适用于右递归规则?
不正确的递归错误规则:
argList
: expr {stackNode [ kstack++ ] = ; }
| argList ',' expr {stackNode [ kstack++ ] = ; }
样本来源:
xy[1, a[2,3] ] = 4 ;
野牛的语法:
argList
: expr {stackNode [ kstack++ ] = ; }
| expr ',' argList {stackNode [ kstack++ ] = ; }
;
statement
: tPV
| expr tPV { $$=; }
;
expr
: tINTEGER { $$ = new_tINTEGER ( ) ; }
| tID '[' argList ']'
{
void** n=(void**) malloc ( sizeof(void**)*kstack ) ;
for(int j=0, i=kstack-1 ; i>=0 ; i-- ) n[j++] = (void*) stackNode[i] ;
$$ = new_tArrayArgList ( ,kstack,n ) ;
kstack=0;
}
| expr tEQ expr { $$ = new_tBINOP ( tEQ,,) ; /* = */}
引用link:
How to build an Array with Bison/Yacc and a Recursive Rule
Left Recursive Rules in Context Free Grammar
问候
克劳迪奥
问题是您使用全局变量 stackNode
和 kstack
来跟踪参数列表。这不是可重入的,因此当您有嵌套参数列表时,处理内部列表会吸收并破坏外部列表的状态,从而导致垃圾。这与左递归和右递归无关,尽管这两种情况会显示不同的损坏。
解决方案是不使用全局变量 -- return $$
中的必要值:
argList
: expr { $$ = new_empty_deque();
push_back($$, ); }
| expr ',' argList { $$ = ; push_front($$, ); }
;
或者(和更高级),使用左递归规则:
argList
: expr { $$ = new_empty_deque();
push_back($$, ); }
| argList ',' expr { $$ = ; push_back($$, ); }
;
我用bison实现了多维数组的管理 这段代码有效,使用左递归规则 然而。说明书上说最好用右边的。 link : Bison Recursive Rules
但是,现在,如果我使用正确的规则,数组将不会被正确解析。 问题是,当我使用正确的规则时,内部数组 a[2,3] returns 是 4 个维度而不是 2 个维度,而另一个数组 x[] 没有维度。
我的问题是:为什么这段代码不适用于右递归规则?
不正确的递归错误规则:
argList
: expr {stackNode [ kstack++ ] = ; }
| argList ',' expr {stackNode [ kstack++ ] = ; }
样本来源:
xy[1, a[2,3] ] = 4 ;
野牛的语法:
argList
: expr {stackNode [ kstack++ ] = ; }
| expr ',' argList {stackNode [ kstack++ ] = ; }
;
statement
: tPV
| expr tPV { $$=; }
;
expr
: tINTEGER { $$ = new_tINTEGER ( ) ; }
| tID '[' argList ']'
{
void** n=(void**) malloc ( sizeof(void**)*kstack ) ;
for(int j=0, i=kstack-1 ; i>=0 ; i-- ) n[j++] = (void*) stackNode[i] ;
$$ = new_tArrayArgList ( ,kstack,n ) ;
kstack=0;
}
| expr tEQ expr { $$ = new_tBINOP ( tEQ,,) ; /* = */}
引用link:
How to build an Array with Bison/Yacc and a Recursive Rule
Left Recursive Rules in Context Free Grammar
问候 克劳迪奥
问题是您使用全局变量 stackNode
和 kstack
来跟踪参数列表。这不是可重入的,因此当您有嵌套参数列表时,处理内部列表会吸收并破坏外部列表的状态,从而导致垃圾。这与左递归和右递归无关,尽管这两种情况会显示不同的损坏。
解决方案是不使用全局变量 -- return $$
中的必要值:
argList
: expr { $$ = new_empty_deque();
push_back($$, ); }
| expr ',' argList { $$ = ; push_front($$, ); }
;
或者(和更高级),使用左递归规则:
argList
: expr { $$ = new_empty_deque();
push_back($$, ); }
| argList ',' expr { $$ = ; push_back($$, ); }
;