2013-10-10 4 views
0

У меня возникают проблемы с этой программой Bison. Он должен получить строку из 1s и 0s с периодом «101.101», умножив их на 2^n. Например:Применение семантических правил для bison

"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.

Bison

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

Lex Файл

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

ответ

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;} 
%% 

Обратите внимание, что закон файл включает в себя "y.tab.h". Это создается с помощью команды

yacc -d file.y 

Бег, как это, где программа под названием «х»:

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

Вы можете изменить код делать свою арифметику, однако вы хотите. Или вы, , можете совершить вызов функции в правиле «s» и вылить биты l и r .

+0

Ударьте меня в него :) Я просто делал одно, но со значением типа 'struct {int val; int pos;}; 'который немного оптимизирует OP. Но продолжайте ... – rici

+0

В любом случае, звучит как ваш лучше. Я ленился. Я не очень хорошо разбираюсь в вещах. Вы могли бы оценивать l и r как два раза на лету. Возможно, из обоих ответов OP сможет это выяснить. –

Смежные вопросы