lex生成lex.yy.c代码流程解析


最近把公司的aix上的一个系统搭回到linux系统。初次接触到yacc(语法分析)与flex(词法分析器)。这里就不能这两个工具作过多的学习式讨论。我只谈谈我遇到的问题,及我的解决办法。
     1,lex filename  生成lex.yy.c的文件。
     2,不管文件,还是主程序运行参数 作为程序的入口。都是直接运行yylex()函数一个对DNF中的数据与符号一个个出栈分析的。
比如我们要对表达式1 AND 2作为词法分析。
               1,首先会运行yy_init,初始化各个buffer段。
               2,yy_act 变量直接指向case YY_END_OF_BUFFER.此时指向的是初始化一个新的buffer
               3,  再 1 ,空格, AND, 2分别 出栈被解析。
               4,yy_act变量直接指向case YY_END_OF_BUFFER.此时表示buffer中的yy_n_chars为0,整个字符串处理结束。
               5,最后会运行到YY_STATE_EOF(INITIAL)分支语句。到此为此整个解析完成。

这里值得一提的是第4部。当主程序发 yy_n_chars为0时,会再次调用YY_INPUT函数尝试从buffer中再取数据。因为我的YY_INPUT是从程序中读取的,所以只能自己写。我把我的YY_INPUT源代码写出来,希望给大家帮助。
#undef YY_INPUT                    //放弃系统提供的输入方式
#define YY_INPUT(b,r,ms)  my_yyinput(b,&r,ms)   //定义自己的my_yyinput

extern char chkexpstr[256];
extern int operator;
static offset = 0;
int my_yyinput( char *buf, int *numBytesRead, int max_size )
{
     int numBytesToRead = max_size;
     int bytesRemaining = strlen(chkexpstr)-offset;
     int i;
     if ( numBytesToRead > bytesRemaining ) { numBytesToRead = bytesRemaining; }
     for ( i = 0; i < numBytesToRead; i++ ) {
       buf[i] = chkexpstr[offset+i];
     }
     *numBytesRead = numBytesToRead;
     offset += numBytesToRead;
     return 0;
}

有一点要小心的就是,如果你的程序要持续解析一个又一个词法的话,记得在
if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
               {
               /* We're scanning a new file or input source.  It's
               * possible that this happened because the user
               * just pointed yyin at a new source and called
               * yylex().  If so, then we have to assure
               * consistency between YY_CURRENT_BUFFER and our
               * globals.  Here is the right place to do so, because
               * this is the first action (other than possibly a
               * back-up) that will match for the new input source.
               */
               (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
               offset = 0;    // 在处理新行时一定要初始化这里。
               YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
               YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
               }

你可能感兴趣的:(lex生成lex.yy.c代码流程解析)