词法分析器的自动生成

来源:互联网 发布:计算机与网络第七版pdf 编辑:程序博客网 时间:2024/04/29 23:46
 关于词法分析器的自动生成
有关词法的自动生成。
工具:flex或是lex,yacc。本次使用flex
准备的基础知识:知道词法分析器的基本原理,了解flex的作用,会基本的正规式的写法。会写makefile更好,这样子你就有可能脱离c语言的IDE了。可以更好的直接运行自己的程序。
基本的学习过程:
   
1. 了解正规式的写法。flex要生成词法分析器的源代码时,需要有一个规格说明,这个说明自然要自己写。
    2. 要能够了解规格说明的基本结构,知道各部分的作用。
    3. 利用规格说明生成lex.yy.c文件,然后根据makefile来编译运行。
基本过程:
   
    /*
 *================================================
 *
 *    xm: 2005xxxxx65
 *
 *
 *==================================================
 */
%{
#include <stdio.h>
#include <stdlib.h>
#define    INT    1
#define    IF    2
#define    THEN    3
#define    WHILE    4
#define    DO        5
#define    ELSE    6
#define    CONST    7
#define    FLOAT        8
#define    DOUBLE        9
#define    SEMICOLON        10
#define    FOR        11
#define    COMMA        12
#define    LPAR        13
#define    RPAR        14
#define    LBRACE        15
#define    RBRACE        16
#define    PLUS        17
#define    MINUS        18
#define    MUTI        19
#define    DIVISION    20
#define    RETURN        21
#define    NEW_LINE        22
#define    ID            23
#define    NUMBER        24
#define    EQU            25
#define    GREATER        26
#define    LESS_THAN    27
#define    BLANK        28
#define    ERROR        -1
%}
digit     [0-9]
letter        [a-zA-Z]
%%
0|([1-9]+digit)*            {printf("number  /n");return NUMBER;}
[1-9]+                {printf("number  /n");return NUMBER;}
letter        {printf("letter  /n");return ID;}
"if"        {printf("Reserved :if /n");return IF;}
"then"    {printf("Reserved :then/n");return THEN;}
"while"    {printf("Reserved :while /n");return WHILE;}
"do"        {printf("Reserved :do /n");return DO;}
"else"    {printf("Reserved :else /n");return ELSE;}
"const"    {printf("Reserved :const /n");return CONST;}
"for"        {printf("Reserved :for /n");return FOR;}
"int"        {printf("Reserved :int /n");return INT;}
"double"    {printf("Reserved :double /n");return DOUBLE;}
"return"    {printf("Reserved :return /n");return RETURN;}
((a-z)+|(A-Z)+|_?)[a-zA-Z0-9]*    {printf("identifiter  /n");return ID;}
";"        {printf("Separation :';'(semicolon) /n");return SEMICOLON;}
","        {printf("Separation :','(comma) /n");return COMMA;}
"("        {printf("Separation :'('(lpar) /n");return LPAR;}
")"        {printf("Separation :')'(rpar) /n");return RPAR;}
"{"        {printf("Separation :'{'(lbrace) /n");return LBRACE;}
"}"        {printf("Separation :'}'(rbrace) /n");return RBRACE;}
"/n"        {printf("Separation :'End_of_Line'(enter) /n");return NEW_LINE;}
"++"        {printf("Operator :'++'-----(plusPLUS) /n");return PLUS;}
"+"        {printf("Operator :'+'-----(plus) /n");return PLUS;}
"-"        {printf("Operator :'-'-----(minus) /n");return MINUS;}
"*"        {printf("Operator :'*'-----(muti) /n");return MUTI;}
"/"        {printf("Operator :'/'-----(division) /n");return DIVISION;}
"="        {printf("Operator :'='(equ) /n");return EQU;}
">"        {printf("Operator :'>'(greater) /n");return GREATER;}
"<"        {printf("Operator :'<'(less_than) /n");return LESS_THAN;}
" "                    //{printf("blank  /n");return BLANK;}
.        {printf("error  /n");return ERROR;}
%%
int yywrap()
{
   return(1);
}

int main()
{   
    int i=0;
        puts("输入一个字符串");
    scanf("%s",yytext);   
    while(0<=i||*yytext!='/0'){
        i=yylex();
    }
    return EXIT_SUCCESS;
}
////////////////////////////////////////////////////////////////////////////////////
makefile 的内容:
    all:lex
lex:lex.yy.o
    gcc -o lex lex.yy.o
lex.yy.o:lex.yy.c
    gcc -c  lex.yy.c
///////////////////////////////////////////////////////////////////////////
基本问题的解决:
    When the scanner receives an end-of-file indication from YY_INPUT, it then checks the `yywrap()' function. If `yywrap()' returns false (zero), then it is assumed that the function has gone ahead and set up yyin to point to another input file, and scanning continues. If it returns true (non-zero), then the scanner terminates, returning 0 to its caller. Note that in either case, the start condition remains unchanged; it does not revert to INITIAL.

If you do not supply your own version of `yywrap()', then you must either use `%option noyywrap' (in which case the scanner behaves as though `yywrap()' returned 1), or you must link with `-lfl' to obtain the default version of the routine, which always returns 1.


eg:
int yywrap()
{
   return(1);
}
   
clean:rm -rf *.o
   
原创粉丝点击