如何从c文件中查找令牌?
我试图从C源文件生成令牌。我已将C文件拆分为一个数组如何从c文件中查找令牌?,c,C,我试图从C源文件生成令牌。我已将C文件拆分为一个数组行,并将整个文件的字存储在一个数组字中 问题在于strtok()函数,该函数在空格字符上拆分行。因此,我没有得到某些分隔符,如括号和方括号,因为它们和其他标记之间没有空格 如何确定哪一个是标识符,哪一个是运算符 迄今为止的代码: int main() { /* ... */ char line[300][200]; char delim[]=" \n\t"; char *words[1000]; cha
行
,并将整个文件的字存储在一个数组字
中
问题在于strtok()
函数,该函数在空格字符上拆分行。因此,我没有得到某些分隔符,如括号和方括号,因为它们和其他标记之间没有空格
如何确定哪一个是标识符,哪一个是运算符
迄今为止的代码:
int main()
{
/* ... */
char line[300][200];
char delim[]=" \n\t";
char *words[1000];
char *token;
while (fgets(&line[i][0], 100, fp1) != NULL)
{
token = strtok(&line[i][0], delim);
while (token != NULL)
{
words[j++] = token;
token = strtok(NULL, delim);
}
i++;
}
for(i = 0; i < 50; i++)
{
printf("%s\n", words[i]);
}
return 0;
}
intmain()
{
/* ... */
字符行[300][200];
char delim[]=“\n\t”;
字符*字[1000];
字符*令牌;
while(fgets(&行[i][0],100,fp1)!=NULL)
{
令牌=strtok(&line[i][0],delim);
while(令牌!=NULL)
{
单词[j++]=标记;
token=strtok(NULL,delim);
}
i++;
}
对于(i=0;i<50;i++)
{
printf(“%s\n”,字[i]);
}
返回0;
}
这是一个棘手的问题,可能需要比答案更深入的问题。尽管如此,我还是会努力的
将输入标记化是关键。目标是简化解析器的任务,解析器将使用文件的内容生成一个抽象语法树。我们如何简化这一点?我们确实认识到那些具有特殊含义的标记,还有标识符、运算符。。。C确实是一种复杂的语言。让我们将语言简化为标记化:我们将从一个典型的计算器开始
输入示例如下:
( 4 +5)* 2
当语法是自由的时,您可以添加或跳过空格,所以正如您已经尝试过的,按空格分割不是一个选项
上面示例的标记化输出是:LPAR、LIT、OP、LIT、RPAR、OP、LIT。其含义如下:
LPAR: Left parenthesis
RPAR: Right parenthesis
LIT: Literal (a number)
OP: Operator (say: +, -, * and /).
因此,完整输出为:
{ LPAR, LIT(4), OP('+'), LIT(5), RPAR, OP('*'), LIT(2) }
您的lexer基本上必须使用状态机在输入字符串中逐字符前进。例如,当您读取一个数字时,您将进入“输入文字”状态,在该状态下,只允许输入其他数字和“.”
现在解析器有了一个更简单的任务。若您使用前面的标记向它输入,它就不必跳过空格,也不必区分负数和负数运算符,它只需在列表或数组中前进即可。正如您所看到的,它可以按照令牌的类型进行操作,其中一些令牌具有关联的数据
无论如何,这只是介绍的介绍。一本书中可能会有关于他的信息。事实上,有很多书都致力于这一主题,比如著名的《来自阿霍、塞蒂和厄尔曼》。更为更新的是“”
最后,lexer在彼此之间非常相似,因此有可能找到它们。你甚至可以找到这类工具的最新版本
希望这(以某种方式)有所帮助。您需要对令牌进行比
strtok
本身处理的更复杂的解析,一次遍历一个字符以确定一个令牌的结束和下一个令牌的开始。找到一个好的C规范。它将从一个标记列表开始,包括它们是什么以及分隔符是什么。请注意,识别C标记非常困难,因为需要识别字符串文字、字符常量和注释(以及尖括号中的标题名称),并且消除了反斜杠换行符等约定,更不用说三角图或注释(两种)。如果是安慰,C++就更差(C++ 14:代码:int b= 0b1000’1001’1100’1010;<代码>任何人或<代码> char b[](“R”/(XYZ)/ /”,“<代码> >,除了我写的“代码> XYZ 扩展多行,包含除<代码>之外的任意文本”//<代码>)。但是简单的代码可能有缺陷(在提到的领域)。您必须识别基本注释(/*…*/
和/…EOL
)、字符串文字、字符文字。是否需要识别反斜杠换行符取决于您将如何处理宏定义之类的内容。理论上,一个关键字可以在一行边界上一分为二,或者字符串的一部分可以在相邻的行上,或者/
注释可以在下一行继续。在实践中,这些都是罕见的问题。将源代码拆分为标记的过程称为词法分析。你可以用手工编写一个特设的词法分析器,这并不太难,但是大多数人认为它是一个单独的工具,一个自动词法分析器生成器的工作。作为Unix一部分的旧版本是lex
;FSF/GNU版本是flex
。如果flex
文档中的教程示例是针对C语言的小型词法分析器,我不会感到惊讶。