
Flex&Bison
ronnie88597
十年磨一剑,剑影开龙鳞
展开
-
3.05 flex和bison进阶,产生C++语法分析器
bison C++版本的语法分析器都是可重入的,所以bison为语法分析器创建了一个类。在使用可重入的语法分析器时,程序员可以创建他所需要数量的实例,然后传入在另一个类中保存的每个实例的应用数据。点击查看这篇文章,其中包含有关可重入语法分析器的信息。每次创建C++ 版本的语法分析器时,bison会创建四个头文件:location.hh和position.hh用来定义位置结构,stack.hh定义内部语法分析器堆栈,以及一个定义语法分析器自生的头文件。前三个头文件内容并不会变化,最后一个头文件则包含该语法分原创 2020-05-14 11:17:19 · 6383 阅读 · 1 评论 -
2.08 Flex如何为部分通用匹配模式定义一个名字
为部分通用匹配模式定义一个名字可以帮助我们分解复杂的表达式,并有助于表达出你的设计意图。定义采用的格式:NAME RE_Expr名字可以包含字母、数字、连字符和下划线,但不能以数字开头。在规则部分,模式可能会包含通过花括号{}括起的基于名字的替换,例如{NAME}。这个名字所代表的表达式将被代入到模式中,并且该表达式会被认为已经用圆括号括起来了,例如:DIG [0-9]...%%{DIG}+ { process_integer(); }{DIG}+\.{DIG}* |\.{DIG}+原创 2020-05-11 16:07:54 · 267 阅读 · 0 评论 -
2.09 Flex单个程序中的多重词法分析器
你可能希望在同一个程序中使用两个部分或者完全不同的记号语法。一个交互式调试解释器可能需要一个词法分析器用于编程语言,还需要另外一个词法分析器用于调试命令。有两种基本的方法来使一个程序处理两个词法分析器:合并的词法分析器或者把两个完整的词法分析器放到程序中合并的词法分析器你可以使用起始状态合并两个词法分析器。每个词法分析器的模式都被加上特定起始状态作为前缀。当词法分析器开始工作时,你需要写一小段代码来让 它进入合适的初始状态,这样就可以选择特定的词法分析器了,例如下面这一段代码(它将会被拷贝到yyl原创 2020-05-11 16:06:15 · 680 阅读 · 0 评论 -
2.07 Flex如何处理上下文相关性
flex提供了多种方式来做到模式的左上下文相关和有上下文相关,也就是与记号的上文和下文相关。左上下文相关有三种方法可以做到左上下文相关:特殊的行首模式字符在模式开头的字符’‘可以让flex只在行首匹配该模式。’'本身并不匹配任何字符,它只用于指定上下文。起始条件%s MYSTATE%%first { BEGIN(MYSTATE); }...<MYSTATE>second { BEGIN(INITIAL); }%%在这个例子中second记号只在first记号出现原创 2020-05-11 15:10:31 · 326 阅读 · 0 评论 -
3.03 bison移进/规约冲突和操作符优先级
移进/规约冲突一般是由文法二义性造成的,关于二义性可以看看这篇文章,以及这位中科院老师的讲解。对于这种问题bison提供了一个聪明的方法,它可以在语法规则之外单独描述优先级。这不仅消除了二义性,也使得语法分析器代码变得短小而且易于维护。bison操作符优先级的规则bison操作符优先级的规则,使用%left,%right,%nonassoc或%precedence声明记号并指定其优先级和关联性。它的语法与%token语法非常相似,如下:%left symbols…%left <type>原创 2020-05-08 22:01:48 · 9964 阅读 · 0 评论 -
3.02 使用bison在语法分析中构建抽象语法树AST
在文章1.06 使用Flex和Bison手写词法分析器和语法分析器,实现一个简单的计算器中,已经做过类似的事情。但与前一篇文章不同的是,本文将在bison语法分析过程中构建AST,让整个计算器项目更像是一个小型的“编译器”。整个程序的目录结构如下所示,源码请看:├── ch3│ ├── 3.02│ │ ├── 3.02_create_AST_with_bison.y│ │...原创 2020-05-08 16:59:10 · 5562 阅读 · 2 评论 -
3.01 bison基本概念及语法介绍
正式开始写bison代码之前,我想应该对bison是如何做语法分析有一定的了解。接下来我们将从移进/规约分析的相关概念开始移进/规约分析,当语法分析器读取记号时,每当它读到的记号无法结束一条规则时,它将把这个记号压人一个内部堆栈,然后切换到一个新状态,这个状态能够反映出刚刚读取的记号,这种行为叫做移进(shift)。当它发现压入的所有语法符号已经可以组成规则的右部时,它将把右部符号全部从堆栈...原创 2020-05-08 10:55:36 · 17156 阅读 · 3 评论 -
2.06 使用Flex处理嵌套的包含文件(include files)与起始条件(start condition)
起始条件(start condition)此外本程序将使用flex一个很强大的特性——起始条件(start condition),它允许我们指定一个特定时刻哪些模式可以被用来匹配。所以首先学习以下起始条件。。。。起始条件定义:起始条件需要在第一部分中声明;声明语句的行首不能有空白符;格式为:%x CONDNAME1或者%s CONDNAME2%x表示将CONDNAME1声明...原创 2020-05-07 16:36:55 · 1161 阅读 · 0 评论 -
2.05 Flex词法分析器的输出管理
2.05 Flex词法分析器的输出管理词法分析器的输出管理比输入管理简单得多,而且完全可选的。同样可以追溯到最早的lex版本,除非你另行设定,否则flex总会执行一条默认的规则:所有没有被匹配的输入都拷贝yyout然后输出。%{/* ...省略部分 */#define ECHO fwrite(yytext, yyleng, 1, yyout)%}%%/* ...省略部分 */. ...原创 2020-05-07 11:10:42 · 612 阅读 · 0 评论 -
2.04 Flex词法分析器的IO结构及输入管理
2.04 Flex词法分析器的IO结构及输入管理大多数情况下,flex词法分析器从文件或STDIN(终端用户)中读取输入。从文件读取和从终端读取存在着一个微小但是重要的差异——预读机制。如果词法分析器从文件读取,它可以通过大段的读操作来提高工作效率。但是如果它从终端读取,用户可能一次只输入一行,并且期望每行输入完成时,词法分析器能够立刻处理。在这种情况下处理效率不再是一个问题。幸运的是,flex...原创 2020-05-07 10:40:43 · 864 阅读 · 0 评论 -
2.02 Flex从文件中读取输入
Flex&Bison学习——2.02 flex从文件中读取输入源码详见/*// file: 2.02_use_yyin_to_read_data_from_file.y// flex词法分析器默认从stdin读取输入//// 除非你对yyin另做安排,词法分析器总是通过yyin文件描述符读取输入,因此为了让flex从文件读取输入// 你只需要在第一次调用yylex之前重新设定...原创 2020-04-26 23:35:07 · 1588 阅读 · 0 评论 -
1.06 使用Flex和Bison手写词法分析器和语法分析器,实现一个简单的计算器
Flex&Bison学习——1.06 使用Flex和Bison手写词法分析器和语法分析器,实现一个简单的计算此处并不打算对Flex的基本用法和格式规则进行详解,有关这些内容请参考。词法解析器部分// file: 1.06y%{# include "1.05_first_calculator_with_bison.tab.h" // 此处需要将语法分析器生成的头文件包含进来,这样F...原创 2020-04-25 17:59:25 · 2242 阅读 · 0 评论 -
1.03 使用Flex将输入的计算表达式识别为token流,然后输入
/*用于将输入的计算表达式识别为token流,然后输入*//*前5个匹配模式,使用了双引号,flex将使用引号内的文本而不会将其解释为正则表达式。*/%%"+" { printf("PLUS\n"); } // 当匹配上了+,将打印PLUS"-" { printf("MINUS\n"); }"*" { printf("TIMES...原创 2020-04-20 10:29:19 · 538 阅读 · 0 评论 -
1.04 Flex实现C语言词法分析器
// file:1.04_NextToken_with_Flex.l/*在词法分析的时候,经常我们需要一个NextToken的函数,这个函数每一次调用返回下一个识别了的Token本例子就是结合Flex来实现NextToken函数的基本功能,来识别C语言中的token该词法分析器仅支持标准C98的关键字识别,新的标准增加的关键字并不支持*/%{enum TokenType{ ...原创 2020-04-19 23:02:42 · 4123 阅读 · 0 评论 -
1.01 Flex基本语法格式和规则详解
Flex&Bison学习——1.1/*一个字数统计(word_counter)程序,程序读入一个文件然后报告这个文件的行数、单词树和字符数。*/%{ // %{ 和 %}之间的代码会被原样照抄到生成的C文件的开头部分。int chars = 0; // 定义变量,用于计数有多少个字符int words = 0; // 定义变量,用于计数有多少个单词int lines ...原创 2020-04-19 17:17:08 · 2401 阅读 · 1 评论