我在这个Bison计划中遇到了麻烦。它必须通过将它们乘以2 ^ n来接收一个1s和0s的字符串,其周期类似于“101.101”。例如:
"101.101" = (1*2^2)+(0*2^1)+(1*2^0)+(1*2^-1)+(0*2^-2)+(1*2^-3)=5.625
这一点说明战俘何时是积极的还是消极的。我有以下语义行为:
S→ L.R
S→ L
L → L1 B
L → B
R → R1 B
R → B
B→ 0
B → 1
Sematic Rules
L.pos=0;R.pos=-1;S.val=L.val+R.val
L.pos=0;S.val=L.val;
L1.pos = L.pos + 1; B.pos = L.pos; L.val = L1.val + B.val;
B.pos = L.pos; L.val = B.val;
R1.pos = R.pos - 1; B.pos = R.pos; L.val = L1.val + B.val;
B.pos = R.pos; L.val = B.val;
B.val=0;
B.val = 1*2^B.pos;
我现在遇到的问题是我不知道为什么.pos变量不起作用,它们的值总是为0.我的野牛代码是:
%{
#include <string.h>
#include <stdio.h>
#include<stdlib.h>
void yyerror (char *string);
%}
%union {
struct named_for_discussion_below {
int pos;
int val;
} pair;
}
%token DOT
%token ZERO
%token ONE
%token l1
%token r1
%type <pair> b l r s;
%%
x: s {/*printf(" the number is %d \n",$1);*/}
;
s: l DOT r {$1.pos=0;$3.pos=-1;$$.val=$1.val+$3.val;/*printf(" the both numbers are %d and %d\n",$1,$3);*/}
| l {$1.pos=0;$$.val=$1.val;/*printf(" the numbers is %d \n",$1);*/}
;
l: l b {$1.pos = $$.pos + 1; $2.pos = $$.pos; $$.val = $1.val + $2.val;printf(" the number is left, l pos is %d and l val is %d \n", $$.pos, $$.val);}
| b {$1.pos = $$.pos; $$.val = $1.val;printf(" the number is left, l pos is %d and l val is %d \n", $$.pos, $$.val);}
;
r: r b {$1.pos = $$.pos - 1; $2.pos = $$.pos; $$.val = $1.val + $2.val;printf(" the number is right, r pos is %d and r val is %d \n", $$.pos, $$.val);}
| b {$1.pos = $$.pos; $$.val = $1.val; printf(" the number is right, r pos is %d and r val is %d \n", $$.pos, $$.val);}
;
b: ZERO {$$.val = 0; printf(" the number is 0, val is %d and pos is %d \n",$$.val,$$.pos);}
| ONE {$$.val = 1*2^($$.pos); printf(" the number is 1, val is %d and pos is %d \n",$$.val,$$.pos);}
;
%%
#include "lex.yy.c"
void yyerror (char *string){
printf ("%s",string);
}
int main (){
yyparse();
}
和lex文件是:
%{
#include <stdio.h>
#include <math.h>
#include "y.tab.h"
%}
BINARY [0-1]
%%
"1" {return ONE;}
"0" {return ZERO;}
"." {return DOT;}
%%
答案 0 :(得分:1)
yacc中的属性始终是合成属性,其值从叶子向上传播到解析树的根,而不是向下传播。
如果要使用继承的属性,则需要使用btyacc之类的工具(您可以获得更新版本here)。这允许您编写代码,如:
%{
#include <string.h>
#include <stdio.h>
#include<stdlib.h>
%}
%union {
double val;
int pos;
}
%token DOT
%token ZERO
%token ONE
%token l1
%token r1
%type <val> b(<pos>) l(<pos>) r(<pos>) s;
%%
x: s {printf(" the number is %f \n",$1);}
;
s: l(0) DOT r(-1) {$$=$1+$3; /*printf(" the both numbers are %f and %f\n",$1,$3);*/}
| l(0) {$$=$1; /*printf(" the numbers is %f \n",$1);*/}
;
l($pos): l($pos+1) b($pos) { $$ = $1 + $2; printf(" the number is left, l pos is %d and l val is %f \n", $pos, $$);}
| b($pos) { $$ = $1; printf(" the number is left, l pos is %d and l val is %f \n", $pos, $$);}
;
r($pos): b($pos) r($pos-1) { $$ = $1 + $2; printf(" the number is right, r pos is %d and r val is %f \n", $pos, $$);}
| b($pos) { $$ = $1; printf(" the number is right, r pos is %d and r val is %f \n", $pos, $$);}
;
b($pos): ZERO { $$ = 0; printf(" the number is 0, val is %f and pos is %d \n",$$,$pos);}
| ONE { $$ = pow(2.0, $pos); printf(" the number is 1, val is %f and pos is %d \n",$$,$pos);}
;
%%
#include "lex.yy.c"
void yyerror (const char *string, ...){
printf ("%s",string);
}
int main (){
yyparse();
}
请注意,我还将val
更改为double
,因为int
只能保留整数。我还将其更改为使用pow
进行取幂(C中的^
是xor)。
答案 1 :(得分:0)
在您的操作中,您希望从$ 1和$ 2分配给$$。因此,$$应位于'='的左侧,$ 1和右侧的$ 2。所以...
l: l b {$1.pos = $$.pos + 1; $2.pos = $$.pos; $$.val = $1.val + $2.val;printf(" the number is left, l pos is %d and l val is %d \n", $$.pos, $$.val);}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| b {$1.pos = $$.pos; $$.val = $1.val;printf(" the number is left, l pos is %d and l val is %d \n", $$.pos, $$.val);}
^^^^^^^^^^^^^^^^
;
还有其他几种相同的品种。
r: r b {$1.pos = $$.pos - 1; $2.pos = $$.pos; $$.val = $1.val + $2.val;printf(" the number is right, r pos is %d and r val is %d \n", $$.pos, $$.val);}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| b {$1.pos = $$.pos; $$.val = $1.val; printf(" the number is right, r pos is %d and r val is %d \n", $$.pos, $$.val);}
^^^^^^^^^^^^^^^
我不清楚你的表达式应该是什么,但$$应该是1美元和2美元的函数。
答案 2 :(得分:0)
$$
是语义操作的结果,因此将其作为赋值的来源是没有意义的。此外,您不能向下传递值,您必须使用其他方法将值传递给更基本的规则(如全局变量)。