自己的应用程序中使用它。
配置文件定义了需要在待分析的文件中查找的字符序列,以及当发现该序列之后应该进行什么操作。
该文件的格式十分简单,即指定输入序列和相应的结果,用空格(或制表符)隔开。
例如:sequence do-something清单 2 显示了一个非常简单的定义,它可以接受单词并根据提供的单词打印出一个字符串。
清单 2. 简单的 lex 定义include ltstdio.hgtbegin printfquotStartednquothello printfquotHello yourselfnquotthanks printfquotYour welcomenquotend printfquotStoppednquot代码中的第一块由 ... 定义,表示将其中的文本插入到生成的 C 源代码中。
在本示例中,因为后面使用了 printf 函数,所以必须确保包含了 stdio.h Header。
代码中的第二块由 序列标识,其中包含了要识别的字符串输入和相应结果的定义。
在上述的这些情况下,对于一个简单的单词,将打印出合适的响应。
回页首生成 C 源代码要生成能够真正分析输入文本的 C 源代码,可以对清单 1 所示的文件运行 lex(或 flex) Lex/flex 文 。
件点号后缀为 l,所以上面的文件可能名为 exampleA.l。
要生成相应的 C 源代码: flex exampleA.l不管您使用哪种工具,其输出都将为 lex.yy.c。
缺乏勇气的人往往不敢仔细研究这个文件,分析器内部的处理过程的确非常复杂,并且建立在基于表格的复杂分析系统的基础上,该系统可以根据原始 lex 定义中的定义对输入文本进行匹配。
因为存在这样的关联,所以该代码相当占用内存,特别是对于那些很大且很复杂的文件。
与 lex 相比,flex 的优点在于它提供了大量附加的选项以改进性能(针对内存或速度)、调试选项和对扫描器行为更好的控制(例如,可以忽略某些情况)。
在生成 C 源代码时,通过使用 -l 命令行选项,您可以生成与原始的 lex 工具生成的源代码非常接近的 C 源代码。
既然已经有了 C 源代码,那么您可以将其编译为相应的应用程序以测试该处理过程: gcc -o exampleA lex.yy.c -lflflex 库(使用 -lfl 进行包含,而 lex 则使用 -ll)包含执行分析代码的简单的 main 函数。
当运行生成的应用程序时,它将等待输入。
清单 3 显示了该应用程序的输入(和输出)。
清单 3. 简单 lex 应用程序的输入/输出 exampleAbeginStartedhelloHello yourselfendStoppedthanksYour welcomehello thanksHello yourself Your welcomehello RobertHello yourself Robert对于单行输入 begin,该应用程序根据您所提供的命令进行响应,在本示例中,将打印出单词Started。
对于包含多个识别单词的行,该应用程序分别运行多个命令,并以空格隔开。
对于无法识别的标记(包括空白字符),仅对其进行回显。
这个示例介绍了该系统的基本操作,但是您仅仅使用了标准的单词。
要使用其他的组合,如字符和元素,有各种不同的解决方案可供使用。
回页首识别元素可识别的元素可以不是前面介绍的固定字符串,标识符支持正则表达式和特殊(例如标点符号)字符,如清单 4 所示。
清单 4. 正则表达式和特殊字符include ltstdio.hgta-z printfquotLowercase wordnquotA-Z printfquotUppercase wordnquota-ZA-Z printfquotWordnquot0-9 printfquotIntegernquot0-9. printfquotFloatnquotquotquot printfquotSemicolonnquotquotquot printfquotOpen parenthesesnquotquotquot printfquotClose parenthesesnquot清单 4 中的示例应该是一目了然的,并且对于需要进行分析的任何正则表达式或特殊字符都可以使用相同的原则。
回页首真正的标记化前面的示例所构建的 C 源代码实质上是独立的。
尽管使用这种方法没有什么问题,但是对于分析包含多个单词、短语或序列的给定指令中的文本或其他条目的情况,这种方法并不是很有价值。
使用这种方式分析序列需要一个语法分析器,而它将定义标记序列。
但是语法分析器必须知道要分析的是什么标记。
在 lex 定义中,当识别标记时所进行的操作是回显字符串,如果要返回一个识别标记,那么需要对该操作进行更改。
例如,您可以如清单 5 所示对原始示例进行重写。
清单 5. 返回标记include ltstdio.hgtinclude lty.tab.hgtbegin return BEGINhello return HELLOthanks return THANKSend return END现在,当识别了 hello 标记时,不再是打印一个字符串,而是返回标记的名称。
在 yacc 中,将使用这个名称来建立相应的语法。
在这个示例中,没有显式地定义这些标记名称。
实际上是在 y.tab.h 文件中指定了这些标记名称,而在分析 yacc 语法文件时由 yacc 自动生成该文件。
回页首提取变量数据如果要提取一个.
上一篇:
c++程序设计实践报告简单计算器模版
下一篇:
“海德格尔学案”对中国学人的启示