Подсчет переменных, массивов в lex / flex

#c #arrays #flex-lexer #lex

#c #массивы #flex-lexer #lex

Вопрос:

Я недавно начал изучать lex и попробовал несколько примеров. Я пытаюсь подсчитать количество переменных, начинающихся с «a» и заканчивающихся цифрой, и количество одномерных массивов.

 %{
#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 amp;amp; (fh = fopen(argv[1], "r")))
        yyin = fh;
printf("%d %d",count1,count2);
yylex();
}
  

Я пытаюсь подсчитать (1) количество переменных, начинающихся с ‘a’ и заканчивающихся цифрой, и (2) количество одномерных массивов. Входные данные поступают из файла «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];

}
  

Оба счетчика показывают ноль, а выходные данные:

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

}
  

Кроме того, как мне подсчитать те переменные, которые попадают в обе категории?

Ответ №1:

У вас неправильный порядок в вашем main . Вы также можете использовать макросы, чтобы сделать длинные регулярные выражения более удобочитаемыми.

 %{
#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 %sn",yytext);
                                     count1  ;
                                   }
{TYPE}{SPACE}{ID}"["{DIGIT} "]"      {
                                     printf("222 %sn",yytext);
                                     count2  ;
                                   }
%%
void main(int argc, char **argv)
{
  FILE *fh;
  if (argc == 2 amp;amp; (fh = fopen(argv[1], "r"))) {
    yyin = fh;
  }
  yylex();
  printf("%d %dn", count1, count2);
}
  

Запуск с файлом

 //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];

}
  

Результаты на выходе

 //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
  

Если вы хотите ограничить вывод токенами — вам нужно дополнительно обрабатывать новые строки, поэтому

 %{
#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 %sn",yytext);
                                     count1  ;
                                   }
{TYPE}{SPACE}{ID}"["{DIGIT} "]"      {
                                     printf("222 %sn",yytext);
                                     count2  ;
                                   }
.
n
%%
void main(int argc, char **argv)
{
  FILE *fh;
  if (argc == 2 amp;amp; (fh = fopen(argv[1], "r"))) {
    yyin = fh;
  }
  yylex();
  printf("%d %dn", count1, count2);
}
  

Результаты на выходе

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