gpt4 book ai didi

c - Lex/flex 程序,用于计算 id、语句、关键字、运算符等

转载 作者:太空宇宙 更新时间:2023-11-04 08:10:28 26 4
gpt4 key购买 nike

%{
#undef yywrap
#define yywrap() 1
#include<stdio.h>
int statements = 0;
int ids = 0;
int assign = 0;
int rel = 0;
int keywords = 0;
int integers = 0;
%}
DIGIT [0-9]
LETTER [A-Za-z]
TYPE int|char|bool|float|void|for|do|while|if|else|return|void
%option yylineno
%option noyywrap

%%
\n {statements++;}
{TYPE} {/*printf("%s\n",yytext);*/keywords++;}
(<|>|<=|>=|==) {rel++;}
'#'/[a-zA-Z0-9]* {;}
[a-zA-Z]+[a-zA-Z0-9]* {printf("%s\n",yytext);ids++;}
= {assign++;}
[0-9]+ {integers++;}
. {;}

%%
void main(int argc, char **argv)
{
FILE *fh;
if (argc == 2 && (fh = fopen(argv[1], "r"))) {
yyin = fh;
}
yylex();
printf("statements = %d ids = %d assign = %d rel = %d keywords = %d integers = %d \n",statements,ids,assign,rel,keywords,integers);
}

//输入文件.c

#include<stdio.h>
void main(){
float a123;
char a;
char b123;
char c;
int ab[5];
int bc[2];
int ca[7];
int ds[4];
for( a = 0; a < 5 ;a++)
printf("%d ", a);
return 0;
}

输出:

include
stdio
h
main
a123
a
b123
c
ab
bc
ca
ds
a
a
a
printf
d
a
statements = 14 ids = 18 assign = 1 rel = 3 keywords = 11 integers = 7

我正在打印标识符。 #include<stdio.h>被算作标识符。我该如何避免这种情况?

我试过了'#'/[a-zA-Z0-9]* {;} rule:action 对,但它仍被视为标识符。文件是如何被标记化的?

还有 %d printf 中的字符串被算作一个标识符。我明确写过标识符只能以字母开头,那为什么是%d被推断为标识符?

最佳答案

  1. I have tried '#'/[a-zA-Z0-9]* {;} rule:action pair but it [include] is still being counted as identifier. How is the file being tokenized?

    token 一次被识别一个。每个标记都从前一个标记结束的地方开始。

    '#'/[a-zA-Z0-9]* 匹配 '#' 提供紧随其后的是 [a-zA-Z0-9]*。您的意思可能是 "#"/[a-zA-Z0-9]*(带双引号)匹配 #,前提是它后面跟着一个字母或数字。请注意,只有 # 匹配; / 之后的模式是“trailing context”,这基本上是一个先行断言。在这种情况下,前瞻是没有意义的,因为 [a-zA-Z0-9]* 可以匹配空字符串,所以任何 # 都会被匹配。在任何情况下,在 # 作为标记匹配后,扫描会在下一个字符处继续。所以下一个标记将是 include

    由于拼写错误,该模式不匹配。 (源代码中没有撇号。)因此,实际匹配的是您的“后备”规则:模式为 . 的规则。 (我们称此为后备规则,因为它匹配任何内容。实际上,它应该是 .|\n,因为 . 匹配除换行符以外的任何内容,但只要您有一些匹配换行符的规则,使用 . 是可以接受的。如果你不提供回退规则,flex 将自动插入 ECHO 操作。 )

    因此,# 将被忽略(就像您按预期编写规则时一样)并且扫描将再次使用标记 include 继续。

    如果你想忽略整个预处理器指令,你可以这样做

    ^[[:空白:]]#.* { ;

  2. (from a comment) I am getting stdio and h as keywords, how does that fit the definition that I have given? What happened to the . in between?

    <被回退规则忽略后,匹配stdio。由于 [a-zA-Z]+[a-zA-Z0-9]* 不匹配除字母和数字以外的任何内容,因此 . 不被视为部分的 token 。然后.被fallback规则匹配忽略,然后h被匹配。

  3. Also the %d string in printf is being counted as an identifier.

    不是真的。 % 被回退规则明确忽略(就像 " 一样),然后 d 作为标识符前进。如果你想忽略字符串文字中的单词,您将必须识别并忽略字符串文字。

关于c - Lex/flex 程序,用于计算 id、语句、关键字、运算符等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39928006/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com