用来使用lex来机型词法分析的一个小程序备注一下
这个程序的目标是,读取下面格式的配置文件并且打印出key,value
conf.ini
db_type : mysql
db_name :testdata
db_table_prefix : levin
db_port : 3306
scanner.h
#define TYPE 1
#define NAME 2
#define TABLE_PREFIX 3
#define PORT 4
#define COLON 5
#define IDENTIFIER 6
#define INTEGER 7
scanner.l
%{
#include "scanner.h"
%}
%%
: return COLON;
"db_type" return TYPE;
"db_name" return NAME;
"db_table_prefix" return TABLE_PREFIX;
"db_port" return PORT;
[a-zA-Z][_a-zA-Z0-9]* return IDENTIFIER;
[1-9][0-9]* return INTEGER;
[ \t\n] ;
. printf("unexpected character\n");
%%
int yywrap(void)
{
return 1;
}
scanner.c
#include <stdio.h>
#include "scanner.h"
extern int yylex();
extern int yylineno;
extern char* yytext;
char *names[] = {NULL,"db_type","db_name","db_table_prefix","db_port"};
int main(void)
{
int ntoken,vtoken;
ntoken=yylex();
while(ntoken){
printf("%d\n",ntoken);
if( yylex() != COLON){
printf("Syntax error in line %d, Expected a ':' but found %s\n",yylineno,yytext);
return 1;
}
vtoken=yylex();
switch (ntoken){
case TYPE:
case NAME:
case TABLE_PREFIX:
if(vtoken != IDENTIFIER){
printf("Syntax error in line %d, Expected an identifier but found %s\n",yylineno,yytext);
return 1;
}
printf("%s is set to %s \n",names[ntoken],yytext);
break;
case PORT:
if(vtoken != INTEGER){
printf("Syntax error in line %d,Expected an integer but found %s\n",yylineno,yytext);
return 1;
}
printf("%s is set to %s\n",names[ntoken],yytext);
break;
default:
printf("Syntax error in line %d\n",yylineno);
}
ntoken=yylex();
}
return 0;
}
运行方式
lex scanner.l
gcc scanner.c lex.yy.c -o scanner
./scanner <config.ini