1 / 21

使用Flex

使用Flex. 怎样使用 LEX?. LEX 的输入为包含正则表达式及其处理动作的文件 (*.l) 输出为包含词法分析函数 yylex() 的源代码文件 (lexyy.c 或 lex.yy.c) 。用户可将它与其它程序链接即可运行。 LEX 分析采用 DFA 转换表算法。. 怎样写 LEX 的输入文件 ?. 首先要弄清两个基本问题 : 正规式在 LEX 中怎样书写 输入文件的格式和约定. 正则表达式. flex词法分析器的模式使用了正则表达式语言,本质上是扩展的POSIX正则表达式 正则表达式使用元语言来描述想匹配的模式

edmund
Download Presentation

使用Flex

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 使用Flex

  2. 怎样使用LEX? • LEX的输入为包含正则表达式及其处理动作的文件(*.l) • 输出为包含词法分析函数yylex()的源代码文件(lexyy.c或lex.yy.c)。用户可将它与其它程序链接即可运行。 • LEX分析采用DFA转换表算法。

  3. 怎样写LEX的输入文件? • 首先要弄清两个基本问题: • 正规式在LEX中怎样书写 • 输入文件的格式和约定

  4. 正则表达式 • flex词法分析器的模式使用了正则表达式语言,本质上是扩展的POSIX正则表达式 • 正则表达式使用元语言来描述想匹配的模式 • 元语言使用标准的文本字符,一部分代表自身而另一部分代表模式(有特殊意义) • 未说明有特殊意义的文本字符代表其自身,如:字母和数字

  5. 正则表达式中特殊意义的字符 • 字符 含义 • . 匹配除 \n外的任意字符 • [ ] 字符类。匹配括号内的任意字符。 • 如果第一个字符是 ^ 那么它表示否定模式。 • 例: [abC] 匹配 a, b, 和 C中的任何一个。 • - 用来指定范围 • 例如:[A-Z] 指从 A 到 Z 之间的任意一个字符。

  6. 正则表达式中特殊意义的字符 • 字符 含义 • {-}新版本才有,匹配前一个字符类减去后一个字符类,如:[a-z]{-}[jv] • ^ 如果是正则表达式的第一个字符就匹配行首,也被用于方括号中表示补集 • $ 如果是正则表达式的最后一个字符则匹配一行的结尾。 • { } 表示重复(如果它们括起来的是数字)或 • 定义的表达式 (如果它们括起来的是一个名字) 。 • 例: A{1,3} 表示 A 可能出现1次~3次0{3}匹配000, {digit} 名字为digit的正则表达式

  7. 正则表达式中特殊意义的字符 * 匹配0个或者多个上述的模式。 + 匹配1个或者多个上述模式。 ? 匹配0个或1个上述模式。 \ 用来转义元字符。 用来覆盖字符在此表中定义的特殊意义,表示字符本意,如:\n表示换行,\\表示字符\本身,\*表示星号本身 | 表达式间的逻辑或,匹配其中之一,如:性别可表示为male|female

  8. 正则表达式中特殊意义的字符 字符 含义 “<一些符号>” 字符的字面含义。用于元字符。 / 尾部上下文(向前匹配)。 如果在匹配的模版中的“/”后跟有后续表达式, 只匹配模版中“/”前面的部分。 例:输入 A01,那么在模版 A0/1 中的 A0 是匹配的。 但不会匹配串A0或者A02。 ( a) 用于把一系列正则表达式组成一个新表达式,匹配a本身。 % 专用于Lex源程序的段间分割符

  9. 正则表达式举例 正则表达式 含义 joke[rs]匹配 jokes 或 joker。 A{1,2}shis? 匹配 AAshis, Ashis, AAshi, Ashi。 (A[b-e])+ 匹配以A开头、奇数位为A、偶数位为b~e之间的任意字符且长度为大于0的偶数的串。

  10. 程序设计语言正则表达式举例 Lex 中的标记声明类似 C 中的变量名。每个标记都有一个相关的表达式。 标记 相关表达式 含义 数字(nat) ([0-9])+ 1个或多个数字 带符号数(signedNat) (“+”|”-”)? Nat 带符号的整数 字符(chars) [A-Za-z] 1个任意字符 空格(blank) " " 一个空格 字(word) (chars)+ 1个或多个 chars 标识符(id) [A-Za-z][A-Za-z0-9]*以字母开头后跟 任意字母或者数字

  11. 注:有一个将输入串原样照抄到输出串的默认动作, 所有不匹配的串都将执行这个动作. 因此如果Lex用户希望接受整个输入串,而不产生任何 输出,就必须提供与所有可能词形相匹配的规则. Lex 动作 当上述的正规式被匹配的时候,Lex将运行相应的动作.

  12. Lex 动作 ——滤掉某些输入 使用一个 C的空语句 ; 例: 滤掉三种空格的字符(空格,tab和回车换行) [ \t\n] ; 省略动作的另一个简单的方法是使用动作字符|, 表示这条规则的动作与下一条规则相同. 上例也可写为:“”| "\t"| "\n" ;

  13. Lex动作 ——输出正规式真正匹配的内容 例:正规式[a-z]+ [a-z]+ printf("% s",yytext); 或 [a-z]+ ECHO; 注:Lex 将匹配的字符串存在外部字符数组yytext中

  14. Lex动作 ——计数 Lex中使用计数器yyleng来表示被匹配的字符个数. 例:对输入串中的单词的个数和字符的个数进行计数, 用语句 [a-zA-Z]+ {words++; chars+=yyleng;} 匹配的串的最后一个字符可用以下方式访问 yytext[yyleng-1]

  15. 2.6.2 LEX输入文件的格式 Lex应用举例(一) 例 给文本添加行号的扫描程序% { /* 在源代码中加行号的LEX程序* / #include <stdio.h> int lineno = 1; % } line .*\n %% {line} { printf ( "%5d %s", lineno++, yytext ); } %% main( ) { yylex(); return 0; }

  16. 2.6.2 LEX输入文件的格式 Lex应用举例(二) 例.只输出以a开头和a结尾的所有行的Lex 输入文件: % { #include <stdio.h> % } ends_with_a .*a\n begins_with_a a.*\n % % {ends_with_a} ECHO; {begins_with_a} ECHO; .*\n ; % % main( ) { yylex( ); return 0; }

  17. 2.6.2 LEX输入文件的格式 Lex应用举例(三) 例 将除c-风格注释外所有的大写字母转变成小写字母的程序: % { #include <stdio.h> #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif % } % %

  18. 2.6.2 LEX输入文件的格式 Lex应用举例(三) [A-Z] {putchar(tolower(yytext[0])); /* yytext[0]为找到的单大写字母 */ } "/*" { char c ; int done = FALSE; ECHO ; do { while ((c=input())!='*') putchar( c ) ; putchar( c ) ; while( ( c = input( ) ) = = ‘ * ’) putchar( c ) ; putchar( c ) ; if (c == '/') done = TRUE; } while (!done); } % % void main(void ){ yylex();}

  19. 2.6.2 LEX输入文件的格式 Lex约定 (1) 二义性的解决 • Lex输出总是首先将可能的最长子串与规则相匹配。 • 如果某个子串可与两个或更多的规则匹配,则L e x的输出将找出列在行为部分中的第1个规则。 • 如果没有规则可与任何非空子串相匹配,则缺省行为将下一个字符复制到输出中并继续下去。

  20. Lex约定 (2) C代码的插入 • 任何写在定义部分% {和% }之间的文本将被直接复制到外置于任意过程的输出程序之中。 • 辅助过程中的任何文本都将被直接复制到Lex 代码末尾的输出程序中。 • 将任何跟在行为部分(在第1个% %之后)的正则表达式之后(中间至少有一个空格)的代码插入到识别过程yylex的恰当位置,并在与对应的正则表达式匹配时执行它。代表一个行为的C代码可以既是一个C语句,也可以是一个由任何说明及由位于花括号中的语句组成的复杂的C语句。

  21. (3) 内部名字 列出了在本章中所提到过的Lex内部名字。 表 一些L e x内部名字 Lex 内部名字含义/使用 lex.yy.c或lexyy.c Lex 输出文件名 yylex Lex 扫描例程 yytext 当前行为匹配的串 yyin Lex 输入文件(缺省: stdin) yyout Lex 输出文件(缺省: stdout) input Lex 缓冲的输入例程 ECHO Lex 缺省行为(将yytext打印到yyout)

More Related