Compiler construction 在C中构建Pascal编译器时的指针问题
我在编译器的词法分析方面遇到了一些问题 我声明了以下指针Compiler construction 在C中构建Pascal编译器时的指针问题,compiler-construction,pascal,lexical,Compiler Construction,Pascal,Lexical,我在编译器的词法分析方面遇到了一些问题 我声明了以下指针 char *words[29]={ "program", "label", "integer", "word", "char", "byte", "shortint", "logint", "real", "single", "double", "s
char *words[29]={
"program",
"label",
"integer",
"word",
"char",
"byte",
"shortint",
"logint",
"real",
"single",
"double",
"string",
"boolean",
"var",
"procedure",
"function",
"begin",
"end",
"if",
"then",
"else",
"or",
"and",
"div",
"not",
"do",
"while",
"mod"
};
char message[30];
然后我尝试在函数中使用它
for(handle=0;(&words[handle] != NULL);handle++)
{
message = &words[handle];
if(!strcmp(token,message))
message='words';
}
但我在尝试执行时收到以下错误:
关于(线路信息)=
&文字[手柄];):警告C4047:“=”
:“char[30]”的级别不同
来自“char**”的间接寻址
关于(线路信息)=
&单词[句柄];):错误C2106:“=”:
左操作数必须是l值
关于(行消息='words';):
错误C2015:中的字符太多
不变的
关于(行消息='words';):
错误C2106:“=”:必须使用左操作数
是l值吗
我不能用那种方式处理指针吗?
你有什么建议吗?三件事:
&
)是无关的。words[handle]
的类型是char*
,即字符串,因此您就有了所需的内容。您不需要获取该char*
的地址=
直接分配给消息
,因为它是一个数组。C语言不是一种非常花哨的语言。您可以将message
更改为char*message
,使其成为指针而不是数组;或者您可以使用strcpy(dst,src)
函数复制到它,就像这样:strcpy(message,“words”)
for
循环在words
数组中查找NULL
指针,这样它就知道何时停止——但数组中没有NULL
!您需要在末尾添加NULL
。正如所写的那样,只有常规字符串,因此循环将永远找不到它正在寻找的空指针,并将冲入未知的内存区域&
)是无关的。words[handle]
的类型是char*
,即字符串,因此您就有了所需的内容。您不需要获取该char*
的地址=
直接分配给消息
,因为它是一个数组。C语言不是一种非常花哨的语言。您可以将message
更改为char*message
,使其成为指针而不是数组;或者您可以使用strcpy(dst,src)
函数复制到它,就像这样:strcpy(message,“words”)
for
循环在words
数组中查找NULL
指针,这样它就知道何时停止——但数组中没有NULL
!您需要在末尾添加NULL
。正如所写的那样,只有常规字符串,因此循环将永远找不到它正在寻找的空指针,并将冲入未知的内存区域希望有帮助 这里有很多错误:
- 不要使用&words[handle],而是使用 字[柄]
- 通过message='words',您试图做什么?这里至少有3个错误:字符串使用双引号,而不是单引号;信息是一个常数,你不能改变它;要复制字符串,需要使用strcpy(),而不仅仅是=运算符
- 如果字符串相等,则strcmp()返回0;你需要改变你的逻辑
- 您忘记在数组末尾包含NULL
- 不要使用&words[handle],而是使用 字[柄]
- 通过message='words',您试图做什么?这里至少有3个错误:字符串使用双引号,而不是单引号;信息是一个常数,你不能改变它;要复制字符串,需要使用strcpy(),而不仅仅是=运算符
- 如果字符串相等,则strcmp()返回0;你需要改变你的逻辑
- 您忘记在数组末尾包含NULL
- 您的代码有很多问题。首先,您应该将关键字数组声明为
const char*words[]
。将字符串常量声明为char*
,而不使用const
,这是一种糟糕的做法;只有在遗留代码仍然可以编译的情况下才允许使用它
您不应该在声明中指定数组大小29,因为它是脆弱的。您应该只使用空括号,让编译器计算出数组大小。您可以通过执行sizeof(words)/sizeof(words[0])
来获得数组的大小,即使您从words
中添加或删除元素,该操作仍然是正确的
接下来,您的for
循环将永远不会终止(尽管它几乎肯定会在某个点发生故障)。获取值的地址永远不会产生空指针,因此&words[handle]!=NULL
将始终为真。迭代循环的正确方法是只计算条目数:
for(handle = 0; handle < sizeof(words)/sizeof(words[0]); handle++)
在那里的最后一个语句中,应该在单词
周围使用双引号,使其成为字符串常量。单引号用于单字符常量(例如,'A'
)。虽然从技术上讲,它们可以包含多个字符,但结果整型常量的endianness是由实现定义的,在本例中它们不是您想要的
我也不太清楚您想用
message=“words”做什么代码>行。如果你想用words
变量做一些聪明的把戏,现在就停下来,它是行不通的。C没有任何类型的反射。您的代码有很多问题。首先,您应该将关键字数组声明为const char*words[]
。将字符串常量声明为char*
,而不使用const
,这是一种糟糕的做法;只有在遗留代码仍然可以编译的情况下才允许使用它
您不应该在声明中指定数组大小29,因为它是脆弱的。你应该只使用空括号,让
const char *message;
...
message = words[handle];
if(!strcmp(token, message))
message = "words";