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*2B.pos;  

我的问题是我不知道如何将 .val 和 .pos 之类的变量添加到 Bison 文件中,然后实现 C 代码编程。

野牛

%{
#include <string.h>
#include <stdio.h>
#include<stdlib.h>
void yyerror (char *string);
int down =0;

%}
%token r1
%token l1
%token DOT
%token ZERO
%token ONE

%%

s: l DOT r
 | l
 ;

l: l1 b
 | b
 ;

r: r1 b
 |b
 ;

b: ONE
 | ZERO
 | error
 ;

%%
#include "lex.yy.c"

void yyerror (char *string){
  printf ("%s",string);
}

main (){
    yyparse();
}

莱克斯文件

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

1 回答 1

1

我写了这个,它不完全是你想要的,但它展示了如何在 yacc 中给规则一个类型以及如何将 C 代码放入规则中。

The C code is in braces { } 
$$ means "this rule"
$1 means "argument 1"
$2 means "argument 2"

So the rule
    r : r b     
and the code 
   { $$ = $1 << 1 | $2; } 
means 
   r = r << 1 | b

yacc 文件是:

%{
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void yyerror (char *string);
int down =0;

%}

%union { // %union is needed to tell yacc about the types your rules will return
    unsigned val; // rules with type "val" will return unsigned
};


%token DOT
%token ZERO
%token ONE

%type <val> l r b; // rules l, r, and b are of type val

%%

s : l DOT r { printf("l.r = 0x%x.0x%x\n", $1, $3); }
  | l       { printf("l = 0x%x\n", $1); }
  ;

l : l b     { $$ = $1 << 1 | $2; } // l = l << 1 | b
  | b       { $$ = $1; } // l = b
  ;

r : r b     { $$ = $1 << 1 | $2; } // r = r << 1 | b
  | b       { $$ = $1; } // r = b
  ;

b : ONE     { $$ = 1; } // b = 0
  | ZERO            { $$ = 0; } // b = 1
  // | error
  ;

%%
//#include "lex.yy.c"

void yyerror (char *string){
  printf ("%s",string);
}

int yywrap() { return 1; }

int main (){
    yyparse();
    return 0;
}

文件

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

请注意,lex 文件包含“y.tab.h”。这是由命令创建的

yacc -d file.y

运行是这样的,程序命名为“x”:

[Charlies-MacBook-Pro:~] crb% cat i
011.110
[Charlies-MacBook-Pro:~] crb% x < i
l.r = 0x3.0x6

您可以根据需要更改代码进行算术运算。或者您可以在“s”规则中进行函数调用,然后在其中倾倒 l 和 r 位。

于 2013-10-10T18:45:45.810 回答