-2

我编写了以下词法分析器。它适用于以下输入:c&3&f、(3|6)&c、f^1。然而,我得到的 strtol 结果并不一致。当我运行 <3|3 时,它将第一个 3 值的十六进制 3 转换为十进制 8,然后将第二个值正确地转换为 3。这是我的整个程序。问题出在最后一个函数中。我添加了 printf 来调试我的代码。(通过 stdin < 传递一个文本文件以运行。每行新表达式)

代码也可以在: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&3&f 和 <3|3 运行它的结果如下:

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

正如您所看到的,第二个表达式的第一个“TOKEN int”值应该是 3,但它返回 8。然后它正确地将 3 转换为 3。有谁知道为什么会这样?strtol如何转换为十进制?

4

1 回答 1

1

改变:

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

进入:

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

(假设您只想处理一位数)。

当您strtol()在前一种情况下进行操作时,它需要一个 C 风格的字符串,并且您提供的内容不能保证以空值结尾。

所以可能发生的事情是你的记忆里有类似38q的东西,会strotol(temp,NULL,16)变成什么样56158

于 2014-11-13T02:34:58.363 回答