




已阅读5页,还剩7页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1.内置变量 yy_create_buffer:见后面的缓冲管理 yy_delete_buffer:见后面的缓冲管理 yy_flex_debug:见后面的缓冲管理 yy_init_buffer:见后面的缓冲管理 yy_flush_buffer:见后面的缓冲管理 yy_load_buffer_state:见后面的缓冲管理 yy_switch_to_buffer:见后面的缓冲管理 yyin: 输入缓冲流的文件指针,可以被替换以实现解析某个自定义的文件 yyleng:当前匹配字串的长度 yylex: 解析函数,接口 yylineno:当前匹配的文件行号 yyout: 输出流的指针 yyrestart: 手动调用yyrestart.会重启解析 yyrestart( yyin );一般是打开某个文件之后,yyrestart(yyin)再解析. yytext: 当前匹配的字串 yywrap: 解析一个文件完毕之后,会调用yywrap:返回1表示结束,0表示继续(此时最好重新打开yyin或者重置yyin流) 2. 几个重要函数:1). yymore(): yymore()的含义是,当当前匹配的字串之后,想把后面配置的字串附加到这个字串后面,组成新的token返回. 比如: % mega- ECHO; yymore(); kludge ECHO; 如果:“mega-kludge the following will write mega-mega-kludge to the output。 为什么呢? 首先遇到 mega-,接着被more了一下,因此就会把kludga附加到mega-后面,而后面的kludge的动作又是打印,因此会打印出:mega-mega-kludge 2). yyless(): yyless()的含义是:当当前的匹配之后,我想只返回前面几个字符,并且把后面回退到输入比如: % foobar ECHO; yyless(3); a-z+ ECHO; input foobar the following will write out foobarbar: 为什么呢? foobar输入之后,匹配foobar,ECHO打印出来,接着yyless(3),则输入流变为bar了(yytext为foo).接着再匹配,于是匹配 到a-z+,因此再次打印出bar. 3).BEGIN: flex下一个起始解析状态。见第3节,flex的状态. 4).REJECT: 相当于拒绝此匹配,让系统重新找下一个匹配。abcd, it will write abcdabcaba to the output: % a | ab | abc | abcd ECHO; REJECT; .|n /* eat up any unmatched character */ 5).unput(c): 把c重新放到输入流。 6).input(): 读取输入流下一个字符 7).yyrestart(): 该函数迫使yylex重新解析。yyrestart有个函数指针流,可以再打开之后,重新使用yyrestart(). 3. 解析源管理: 1). 默认是从yyin获取,而yyin则是stdout,也可以是其它文件。 if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; 2). 如果你打开了一个文件,并把yyin指向此文件,则从该文件中读取.比如: 在main中: FILE* fp = NULL; fp = fopen(hell.txt, r); yyin = fp; 之后再使用yylex() 则flex从hell.txt中读取信息并解析. 3).从字符串中解析 先使用下列函数,转化缓冲,之后再使用yylex() a. yy_scan_string(char*).使用了yy_scan_string(char*)之后,flex会把char*放到yy的输入缓冲中(会调用到yy_switch_to_buffer.) b. yy_scan_bytes(const char *base, int len); c. yy_scan_buffer(char *base, yy_size_t size) 这几个函数内部都使用的是缓冲切换的创建等函数,见后面的章节. 4).利用EOF内置规则,重新打开多个文件输入: 比如: if ( *+filelist ) yyin = fopen( *filelist, r ); else yyterminate(); 5).多缓冲问题: a.此问题可以按上面的 或者 yywrap解决。 b.另外一种形式,比如:#include 或者类似于这种,这种形式的话,则不能使用yywrap,来解决了。 这就需要用到在flex动作中手动切换缓冲。flex对每个缓冲有个缓冲输入流指针,指向当前位置,各个被切换的缓冲互不相干扰,这恰好很好地解决了文件包含另外一个文件,而子文件也许要yylex的这种场合. 这就需要使用到flex底层的缓冲管理了.见下节 4. flex的缓冲管理: flex本质上都是对缓冲输入流进行yylex词法分析. 缓冲是个结构体,每个缓冲有个缓冲输入流指针,指向当前位置,各个被切换的缓冲互不相干扰,而相关yyin,yyrestart,yy_create_buffer,yy_scan_string系列函数都是操纵flex底层缓冲的. flex缓冲是一个结构体: 我们以下面的词法规则为例子:(来自flex官方网站的注解) /* the incl state is used for picking up the name * of an include file */ %x incl % #define MAX_INCLUDE_DEPTH 10 YY_BUFFER_STATE include_stackMAX_INCLUDE_DEPTH; int include_stack_ptr = 0; % % include BEGIN(incl); a-z+ ECHO; a-zn*n? ECHO; t* /* eat the whitespace */ tn+ /* got the include file name */ if ( include_stack_ptr = MAX_INCLUDE_DEPTH ) fprintf( stderr, Includes nested too deeply ); exit( 1 ); include_stackinclude_stack_ptr+ = YY_CURRENT_BUFFER; yyin = fopen( yytext, r ); if ( ! yyin ) error( . ); yy_switch_to_buffer( yy_create_buffer( yyin, YY_BUF_SIZE ) ); BEGIN(INITIAL); if ( -include_stack_ptr 0 ) yyterminate(); else yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( include_stackinclude_stack_ptr ); YY_BUFFER_STATE就是一个缓冲。该lex文法使用到了,这个是状态,见4节的flex的状态管理.目前只需要知道它是个状态即可.在incl状态下才进行 t*的规则匹配. 见上面的描述,指某个输入流到了末尾则到了这个状态. BEGIN(INITIAL)类似于BEGIN(0),表示状态从开头解析(0表示不带状态的解析,也就说规则前没有这个标记的状态. 上面的文法可以知道: a. 在遇到include之后,跳到incl状态。 b. 在incl状态中,跳过空白的字符,得到文件名(include file),先把当前的flexBuffer保存到数组栈,然后打开新的文件,并把flex的当前输入流切换到刚打开的新文件的输入流. c. 切换到INITIAL状态(没有在规则前的默认的状态) d.这里用到了几个宏或者函数: yy_switch_to_buffer, yy_create_buffer,YY_CURRENT_BUFFER,yy_delete_buffer. 这些函数看名字就应该知道其作用了。 4. flex的状态(Start conditions). 上面的缓冲管理已经涉及到状态管理了。flex的状态管理相当于普通词法的扩展。通过flex的状态,大大扩充了词法分析本身的功能。 比如: a. * /* eat up the string body . */ . 表示在STRING状态下才进行 *匹配。 b. . /* handle an escape . */ . 表示在INITIAL,STRING,QUOTE才匹配。. flex的状态怎么使用呢? a. 首先定义:以%开头(flex的申明本质上所有的都是以%开头)定义,有2种: %s,%x,其中%s = %x+INITIAL,也就说是%s的状态为%x定义的+INITIAL状态 b. 在规则域中,使用规则,比如 comment是个状态,则有 .,其中.是个lex规则文法,comment则就是一个状态了. c.有几个特殊内置的状态。INITIAL,*.比如: 规则,则表示这个规则在任何状态下有效. 是个默认状态。 d.某个规则可以支持多个状态,使用“,”隔开。比如规则.如果和重用一个规则的话,则是。 e.flex还提供了一套相关函数: yy_push_state, yy_pop_state, yy_top_state, BEGIN() 可以说有了状态的支持,flex的功能更加强大了,简单的文法分析甚至可以不借助于yacc/bison来做了。 一个完整的例子: %x str % char string_bufMAX_STR_CONST; char *string_buf_ptr; string_buf_ptr = string_buf; BEGIN(str); /* saw closing quote - all done */ BEGIN(INITIAL); *string_buf_ptr = 0; /* return string constant token type and * value to parser */ n /* error - unterminated string constant */ /* generate error message */ 0-71,3 /* octal escape sequence */ int result; (void) sscanf( yytext + 1, %o, &result ); if ( result 0xff ) /* error, constant is out-of-bounds */ *string_buf_ptr+ = result; 0-9+ /* generate error - bad escape sequence; something * like 48 or 0777777 */ n *string_buf_ptr+ = n; t *string_buf_ptr+ = t; r *string_buf_ptr+ = r; b *string_buf_ptr+ = b; f *string_buf_ptr+ = f; (.|n) *string_buf_ptr+ = yytext1; n+ char *yptr = yytext; while ( *yptr ) *string_buf_ptr+ = *yptr+; 5. flex C+的支持 编译时,使用flex -+ 文件,就可以得到.cc的文件,而且flex也会生成C+相关类,对应的类和方法有: FlexLexer:成员方法有: a. yylex(), YYText(), YYLeng(),lineno(), set_debug(),debug(), b. 构造函数yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 ) c. 缓冲:switch_streams(istream* new_in = 0, ostream* new_out = 0),yylex( istream* new_in = 0, ostream* new_out = 0 ) 等等。 例子: / An example of using the flex C+ scanner class. % int mylineno = 0; % string n+ ws t+ alpha A-Za-z dig 0-9 name (alpha|dig|$)(alpha|dig|_.-/$)* num1 -+?dig+.?(eE-+?dig+)? num2 -+?dig*.dig+(eE-+?dig+)? numb
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 智能化技术加速零售行业数字化变革
- 脑中风治疗讲课件
- 护理搬运课件
- 公司各种证件管理制度
- 公司合同协议管理制度
- 公司员工物品储物柜管理制度
- 探索式教育理念下小学建筑设计策略
- 公司私自修改考勤管理制度
- 公司精细化采购管理制度
- 公司给销售买车管理制度
- 期末试卷(试题)(含答案)-2024-2025学年一年级下册数学北师大版
- 上海浦东新区公办学校储备教师教辅招聘笔试真题2022
- 人教版高中政治必修四课本考点总结
- 第5章 自动驾驶仪系统《民航飞机自动飞行控制系统》
- DB4401-T 19-2019涉河建设项目河道管理技术规范-(高清现行)
- 五星级酒店投资预算
- 儿科常用药、用药特点及护理ppt
- 胎心监护以及判读
- 企业资产损失所得税税前扣除鉴证业务操作的指南
- 高等数学(下册)资料期末复习试题与答案
- 四冲程内燃机 机械原理课程设计说明书
评论
0/150
提交评论