我写过以下词法分析器。它适用于以下输入:c& 3& f,(3 | 6)& c,f ^ 1。然而,我得到的strtol结果并不一致。当我运行< 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&amp; 3&amp; f和&lt; 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
正如你所看到的第一个&#34; TOKEN int&#34;第二个表达式的值应该是3,但它返回8.然后它正确地将3转换为3。有谁知道为什么会这样? strtol如何转换为十进制?
答案 0 :(得分:1)
变化:
char temp[1];
temp[0] = token;
成:
char temp[2];
temp[0] = token;
temp[1] = '\0';
(假设您只想处理一位数字)。
如果您在前一种情况下执行strtol()
,那么它会期待一个C风格的字符串,而您所提供的内容并不能保证是空终止的。
所以可能发生的事情是,你的记忆中有38q
,strotol(temp,NULL,16)
会将其变成56
,这将是,当和 - 使用15
编辑,为您提供8
。