2013-10-11 69 views
0

我在這個Bison程序中遇到了麻煩。它必須通過將它們乘以2^n來接收具有諸如「101.101」的句點的1和0的字符串。例如:野牛語義規則變量

"101.101" = (1*2^2)+(0*2^1)+(1*2^0)+(1*2^-1)+(0*2^-2)+(1*2^-3)=5.625 

該點告訴pow何時正面或負面。我有以下語義動作:

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(); 
} 

和法文件是:

%{ 
#include <stdio.h> 
#include <math.h> 
#include "y.tab.h" 
%} 
BINARY [0-1] 
%% 
"1" {return ONE;} 
"0" {return ZERO;} 
"." {return DOT;} 
%% 

回答

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的功能。

+0

我遇到的問題是,.pos應該告訴我這個令牌的位置,它只是停留在0,並且從不真正改變它的數量。這是需要的,因爲它不可能有多少數字在該點的左邊,並且將它們提升到正確的功率,例如101應該知道它的位置是1是位置2,0是位置1並且1是位置0,所以它可以乘以1 * 2 ^(位置) – Xheis

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是一個doubleint只能容納整數。我也將它改爲使用pow來取冪(在C中的^是xor)。