前言
- flex选择更长的匹配,如果两个模式都匹配,选择首先出现的模式;
- 文法与语法分析:构建语法分析树,找出输入记号之间的关系;
- 上下文无关语法,bison中token一般使用大写字母。bison包含三部分构成:声明部分+ 规则部分和C代码部分。使用分号代表规则的结束;
- 语法分析器返回记号时,记号值总被存储在yyval中
- 当规则缺少显示动作时,语法分析器将 1赋值给 $
- bison不分析二义性语法,例如加减法的先后顺序,这里有点绕;后面可以事先设定优先级和分组,解决二义性
几个概念
- 语法起始符号:第一条规则左边的语法符号,整个输入必须被他匹配
- 目标符号:冒号左边的语法符号,用$$代替,右侧语法符号的语义值依次为$1 $2…
- 记号:token,用%token声明
- 动作代码:在每条规则之后,用花括号括起
使用FLEX
正则表达式
- . 匹配除换行符以外任意单一字符
- [] 字符类,匹配方括号内任意一个字符,若起始为^,反向匹配
- [a-z]{-}[jv] 匹配前一个字符类减去后一个字符类的结果
- * 匹配零个或多个紧接在前面的表达式
- + 匹配一个或多个…
- ? 匹配零个或一个…
- “…” 引号内字符被基于字面意义被解释
- () 一系列的正则表达式组成新的正则表达式
- [ \t]* 匹配空字符串
- | 匹配前面的正则表达式或者后面的,作用范围左边所有或右边所有
- / 尾部上下文,匹配斜线前的表达式,并对其后的表达式进行要求,但并不消耗掉其后字符
- {} 当花括号中有一个或两个数字时,表示前一个模式可以匹配的最小最大次数;当里面带有名字时,指向以这个名字命名的模式
- (?a:pattern)或者(?a-x:pattern):Perl风格的模式修饰符。前者用修饰符a修饰模式,后者使用修饰符a但不包含修饰符x来修饰模式。
- 修饰符包含i s x;i标示大小写无关;s将所有字符作为单行匹配,即.可以匹配\n;x忽略空白字符和C风格注释
支持POSIX字符类,[:alnum:] [:alpha:]等
详见P138
处理二义性重复匹配的操作符总是针对邻近的表达式
- 负号的用法,当匹配正负号时[-+]?放在前面,避免被误认为范围
- flex允许两个不同模式匹配相同的输入,dangerous
- 复杂的匹配模式并不会降低其速度,除了尾部上下文符号
- 匹配关键字的模式先于匹配标识符的模式,就能正确匹配关键字
- 上下文相关的词法分析,例如pascal
输入
- -lfl flex提供的库,定义了main例程和y