Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从c文件中查找令牌?_C - Fatal编程技术网

如何从c文件中查找令牌?

如何从c文件中查找令牌?,c,C,我试图从C源文件生成令牌。我已将C文件拆分为一个数组行,并将整个文件的字存储在一个数组字中 问题在于strtok()函数,该函数在空格字符上拆分行。因此,我没有得到某些分隔符,如括号和方括号,因为它们和其他标记之间没有空格 如何确定哪一个是标识符,哪一个是运算符 迄今为止的代码: int main() { /* ... */ char line[300][200]; char delim[]=" \n\t"; char *words[1000]; cha

我试图从C源文件生成令牌。我已将C文件拆分为一个数组
,并将整个文件的字存储在一个数组

问题在于
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语言的小型词法分析器,我不会感到惊讶。