#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