2014-11-13 17 views
-2

다음 어휘 분석기를 작성했습니다. c f, (3 | 6) & c, f^1과 같은 입력에 대해 올바르게 작동합니다. 그러나 strtol에 대한 결과는 일관성이 없습니다. < 3 | 3을 실행하면 처음 3 값에 대해 16 진수 3을 8로 변환 한 다음 두 번째 값으로 3을 올바르게 변환합니다. 이것은 내 전체 프로그램입니다. 문제는 마지막 기능입니다. 내 코드를 디버그하기 위해 printf를 추가했다. (실행 표준 입력 <를 통해 텍스트 파일을 통과 각 라인에 새로운 표정을.). strtol은 어떻게 작동합니까?

코드도에서 찾을 수 있습니다 : Github

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

//Max number of characters on new line from file 
#define LINE_MAX 1028 

char expression[LINE_MAX]; 
int position; 

char next(); 
char peek(); 
int E(); 
int EE(int i); 
int A(); 
int AA(int i); 
int B(); 
int BB(int i); 
int C(); 

int main (int argc, char *argv[]) 
{ 
    char line[LINE_MAX]; 

    while (fgets(line, LINE_MAX, stdin) != NULL) { 

     //remove the newline character for printing the expression 
     size_t strlength = strlen(line); 
     line[strlength-1] = '\0'; 

     //reset global variables 
     position = 0; 
     strcpy(expression, line); 

     int result = E(); 

     printf("%s = %x\n", line, result); 
    } 
} 

char next(){ 
    return expression[position++]; 
} 

char peek(){ 
    return expression[position]; 
} 

int E(){ 
    int st = A(); 
    return EE(st); 
} 

//bitwise "|" OR 
int EE(int i){ 
    char token = peek(); 

    if (token == '|'){ 
     next(); 
     int val = A(); 
     return EE(i | val); 
    }else{ 
     return i; 
    } 
} 

int A(){ 
    int st = B(); 
    return AA(st); 
} 

//bitwise "^" XOR 
int AA(int i){ 
    char token = peek(); 

    if (token == '^'){ 
     next(); 
     int val = B(); 
     return AA(i^val); 
    }else{ 
     return i; 
    } 
} 

int B(){ 
    int st = C(); 
    return BB(st); 
} 

//bitwise "&" AND 
int BB(int i){ 
    char token = peek(); 

    if (token == '&'){ 
     next(); 
     int val = C(); 
     return BB(i & val); 
    }else{ 
     return i; 
    } 
} 

/********************************************************************* 
********************************************************************* 
This is the function I am having a problem with. Strtol is giving me 
inconsistent integer values. 
********************************************************************* 
*********************************************************************/ 
int C(){ 

    char token = next(); 

    if(token == '<'){ 
     //bitwise shift secondToken << 
     printf("BITEWISE LEFT SHIFT: %c\n", token); 
     return (C() << 1) & 15; //0xf; 
    }else if(token == '>'){ 
     //bitwise shift secondToken >> 
     return C() >> 1; 
    }else if(token == '~'){ 
     //bitwise not secondToken ~ 
     printf("BITEWISE NOT: %c\n", token); 
     return (~C()) & 15; 
    }else if(token == '('){ 
     int val = E(); 
     next(); 
     return val; 
    }else{ 
     printf("TOKEN: %c\n", token); 
     //return the token hex value as int 
     char temp[1]; 
     temp[0] = token; 
     printf("TEMP 0: %c\n", temp[0]); 
     printf("TOKEN int: %d\n", (int)strtol(temp, NULL, 16) & 15); 
     return (int)(strtol(temp, NULL, 16) & 15); //0xf; 
    } 
} 

C에 대한 F와 < 3 그것을 실행의 결과 두 번째 표현을위한 최초의 "TOKEN INT"값을 볼 수 있듯이

TOKEN: c 
TEMP 0: c 
TOKEN int: 12 
TOKEN: 3 
TEMP 0: 3 
TOKEN int: 3 
TOKEN: f 
TEMP 0: f 
TOKEN int: 15 
c&3&f = 0 

BITEWISE LEFT SHIFT: < 
TOKEN: 3 
TEMP 0: 3 
TOKEN int: 8 
TOKEN: 3 
TEMP 0: 3 
TOKEN int: 3 
<3|3 = 3 

3해야하지만 8. 그리고 제대로 일 이후 3 3 변환 반환 : | 3 다음과 같다 에서. 왜 이런 일이 일어나는 지 아는 사람이 있습니까? strtol은 어떻게 십진수로 변환합니까?

+0

EE? 에이? 금주 모임? 그들이 당신의 코스에서 가독성에 대해 가르쳐주지 않았습니까? :-) – paxdiablo

+0

@ paxdiablo 그는 우리에게 따라야 할 구체적인 문법을주었습니다. 그 문법은 우리가 기능을 부르기를 원했던 것입니다. 나는 가난한 가독성에 동의한다 ... – orelius

답변

1

변경 :

char temp[1]; 
temp[0] = token; 

로 :

char temp[2]; 
temp[0] = token; 
temp[1] = '\0'; 

(당신은 한 자리 숫자를 처리하고자하는 가정).

앞에서 strtol()을 수행 할 때 C 스타일 문자열을 기대하고 있으며 null 종료가 보장되지 않습니다.

그래서 아마 무슨 일이 일어나고 있는지 당신이 메모리 안에, strotol(temp,NULL,16)15와 에드, 당신에게 8을 줄 것이다 56로이 켜집니다 38q 같은 것을 가지고있어 것입니다.

+0

고맙습니다 !!! 그것은 완벽하게 작동했습니다! 그건 너무 의미가 있습니다. 그레 시아! – orelius