2013-10-10 5 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가 양수인지 음수인지를 알려줍니다. 나는 다음과 같은 의미 조치를 가지고 내가 가진 문제는 내가 들소 파일에 .val과 .POS 같은 변수를 추가 한 다음 C 코드 프로그래밍을 구현하는 방법을 모르겠입니다

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; 

. 내가 쓴

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

답변

1

들소

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

렉스는 당신이 원하는 정확히 아니지만 그것은 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; 
} 

렉스 파일 렉스 파일이 "y.tab.h"를 포함

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

참고. 당신은 그러나 당신이 원하는 당신의 산술 연산을 수행 코드를 변경할 수

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

: 이것은 프로그램이 "X"라는

yacc -d file.y 

실행이처럼 명령에 의해 생성된다. 또는 은 "s"규칙에서 함수 호출을 만들 수 있으며 그 안에 비트 l과 r 을 부어 넣을 수 있습니다.

+0

나를 괴롭힌다. 나는 단지 하나만하고있다. 그러나 값 유형이'struct {int val; int pos;};'는 OP를 조금 더 잘 모델링합니다. 그러나 계속하십시오 ... – rici

+0

어느 쪽이든, 당신 것 같은 소리가 더 낫습니다. 나는 게으르다. 나는 물건을 설명하는 것에 능숙하지 않다. l과 r을 즉시 두 배로 평가할 수 있습니다. 둘 다 답변에서 OP는 그것을 알아낼 수있을 것입니다. –