计算变量,lex / flex中的数组

时间:2022-03-15 09:37:27

I have started learning lex recently and tried a few examples. I am trying to count the number of variables starting with 'a' and ending with a digit and the number of 1D arrays.

我最近开始学习lex并尝试了几个例子。我试图计算以'a'开头并以数字和1D数组的数字结尾的变量数。

%{
#undef yywrap
#define yywrap() 1
#include<stdio.h>
int count1;
int count2;
%}
%option noyywrap
%%

int|char|bool|float" "a[a-z,A-Z,0-9]*[0-9] {count1++;}
int|char|float|bool" "[a-z,A-Z]+[0-9,a-z,A-Z]*"["[0-9]+"]" {count2++;}

%%

void main(int argc,char** argv){
FILE *fh;
    if (argc == 2 && (fh = fopen(argv[1], "r")))
        yyin = fh;
printf("%d %d",count1,count2);
yylex();
}

I am trying to count (1) the number of variables starting with 'a' and ending with a digit and (2) the number of 1D arrays. The input is from a "f.c" file.

我试图计算(1)以'a'开头并以数字结尾的变量数和(2)1D数组的数量。输入来自“f.c”文件。

//f.c

#include<stdio.h>
void main(){
    char a;
    char b;
    char c;
    int ab[5];
    int bc[2];
    int ca[7];
    int ds[4];

}

Both the counts are showing zero and the output is:

两个计数都显示为零,输出为:

0 0#include<stdio.h>
void main(){
         a;
         b;
         c;
         ab[5];
         bc[2];
         ca[7];
         ds[4];

}

Also, how do I count those variables which fall in both of the categories?

另外,我如何计算属于这两个类别的变量?

1 个解决方案

#1


2  

You have the order wrong in your main. You can also use macros to make long regexes more readable.

您的主要订单有错误。您还可以使用宏来使长正则表达式更具可读性。

%{
#undef yywrap
#define yywrap() 1
#include<stdio.h>
  int count1 = 0;
  int count2 = 0;
%}
TYPE int|char|bool|float
DIGIT [0-9]
ID [a-z][a-z0-9A-Z]*
SPACE " "
%option noyywrap

%%

{TYPE}{SPACE}a[a-z0-9A-Z]*{DIGIT}  {
                                     printf("111 %s\n",yytext);
                                     count1++;
                                   }
{TYPE}{SPACE}{ID}"["{DIGIT}+"]"      {
                                     printf("222 %s\n",yytext);
                                     count2++;
                                   }
%%
void main(int argc, char **argv)
{
  FILE *fh;
  if (argc == 2 && (fh = fopen(argv[1], "r"))) {
    yyin = fh;
  }
  yylex();
  printf("%d %d\n", count1, count2);
}

Run with the file

运行该文件

//f.c

#include<stdio.h>
void main(){
    char a123;
    char a;
    char b123;
    char c;
    int ab[5];
    int bc[2];
    int ca[7];
    int ds[4];

}

Results in the output

结果输出

//f.c

#include<stdio.h>
void main(){
    111 char a123
;
    char a;
    char b123;
    char c;
    222 int ab[5]
;
    222 int bc[2]
;
    222 int ca[7]
;
    222 int ds[4]
;

}
1 4

If you want to restrict the output to tokens-only you need to handle newlines extra, so

如果要将输出限制为令牌,则需要额外处理换行符,所以

%{
#undef yywrap
#define yywrap() 1
#include<stdio.h>
  int count1 = 0;
  int count2 = 0;
%}
TYPE int|char|bool|float
DIGIT [0-9]
ID [a-z][a-z0-9A-Z]*
SPACE " "
%option noyywrap

%%

{TYPE}{SPACE}a[a-z0-9A-Z]*{DIGIT}  {
                                     printf("111 %s\n",yytext);
                                     count1++;
                                   }
{TYPE}{SPACE}{ID}"["{DIGIT}+"]"      {
                                     printf("222 %s\n",yytext);
                                     count2++;
                                   }
.
\n
%%
void main(int argc, char **argv)
{
  FILE *fh;
  if (argc == 2 && (fh = fopen(argv[1], "r"))) {
    yyin = fh;
  }
  yylex();
  printf("%d %d\n", count1, count2);
}

Results in the output

结果输出

111 char a123
222 int ab[5]
222 int bc[2]
222 int ca[7]
222 int ds[4]
1 4

#1


2  

You have the order wrong in your main. You can also use macros to make long regexes more readable.

您的主要订单有错误。您还可以使用宏来使长正则表达式更具可读性。

%{
#undef yywrap
#define yywrap() 1
#include<stdio.h>
  int count1 = 0;
  int count2 = 0;
%}
TYPE int|char|bool|float
DIGIT [0-9]
ID [a-z][a-z0-9A-Z]*
SPACE " "
%option noyywrap

%%

{TYPE}{SPACE}a[a-z0-9A-Z]*{DIGIT}  {
                                     printf("111 %s\n",yytext);
                                     count1++;
                                   }
{TYPE}{SPACE}{ID}"["{DIGIT}+"]"      {
                                     printf("222 %s\n",yytext);
                                     count2++;
                                   }
%%
void main(int argc, char **argv)
{
  FILE *fh;
  if (argc == 2 && (fh = fopen(argv[1], "r"))) {
    yyin = fh;
  }
  yylex();
  printf("%d %d\n", count1, count2);
}

Run with the file

运行该文件

//f.c

#include<stdio.h>
void main(){
    char a123;
    char a;
    char b123;
    char c;
    int ab[5];
    int bc[2];
    int ca[7];
    int ds[4];

}

Results in the output

结果输出

//f.c

#include<stdio.h>
void main(){
    111 char a123
;
    char a;
    char b123;
    char c;
    222 int ab[5]
;
    222 int bc[2]
;
    222 int ca[7]
;
    222 int ds[4]
;

}
1 4

If you want to restrict the output to tokens-only you need to handle newlines extra, so

如果要将输出限制为令牌,则需要额外处理换行符,所以

%{
#undef yywrap
#define yywrap() 1
#include<stdio.h>
  int count1 = 0;
  int count2 = 0;
%}
TYPE int|char|bool|float
DIGIT [0-9]
ID [a-z][a-z0-9A-Z]*
SPACE " "
%option noyywrap

%%

{TYPE}{SPACE}a[a-z0-9A-Z]*{DIGIT}  {
                                     printf("111 %s\n",yytext);
                                     count1++;
                                   }
{TYPE}{SPACE}{ID}"["{DIGIT}+"]"      {
                                     printf("222 %s\n",yytext);
                                     count2++;
                                   }
.
\n
%%
void main(int argc, char **argv)
{
  FILE *fh;
  if (argc == 2 && (fh = fopen(argv[1], "r"))) {
    yyin = fh;
  }
  yylex();
  printf("%d %d\n", count1, count2);
}

Results in the output

结果输出

111 char a123
222 int ab[5]
222 int bc[2]
222 int ca[7]
222 int ds[4]
1 4