词法分析器

PASCAL语言子集的词法、语法分析器之实现

对着背影说爱祢 提交于 2020-01-04 23:59:09
针对简单的文法(PASCAL语言子集),制作相应的词法分析器和递归下降的语法分析器。 文法要求如下: 1、 关键字、标识符、数字等: 1.begin 2.if 3.then 4.while 5.do 6.end 10.标识符 11.数字 13.+ 14.- 15.* 16./ 17.: 18.:= 20.< 21.<> 22.<= 23.> 24.>= 25.= 26.; 27.( 28.) 2、 文法规则: 程序 → begin 语句串 end 语句串 → 语句 { ; 语句 } 语句 → 赋值语句 | 条件语句 | 循环语句 赋值语句 → 变量 := 表达式 条件语句 → if 条件 then ( 语句 | 程序 ) 循环语句 → while 条件 do ( 语句 | 程序 ) 表达式 → 项 { + 项 | - 项 } 条件 → 表达式 关系符 表达式 关系符 → < | <> | <= | > | >= | = 项 → 因子 { * 因子 | / 因子 } 因子 → 变量 | 数字 | ( 表达式 ) 变量 → 标识符 一、 词法分析器 词法分析器的任务是清除源文件中多余的空格、换行、制表符等,识别文法符号。按顺序输出识别的标识符及其种别编号,供语法分析器调用。 代码如下: #include<stdio.h> #include<string.h> #include

PASCAL语言子集的词法、语法分析器之实现

丶灬走出姿态 提交于 2020-01-04 23:56:34
针对简单的文法(PASCAL语言子集),制作相应的词法分析器和递归下降的语法分析器。 文法要求如下: 1、 关键字、标识符、数字等: 1.begin 2.if 3.then 4.while 5.do 6.end 10. 标识符 11. 数字 13.+ 14.- 15.* 16./ 17.: 18.:= 20.< 21.<> 22.<= 23.> 24.>= 25.= 26.; 27.( 28.) 2、 文法规则 : 程序 → begin 语句串 end 语句串 → 语句 { ; 语句 } 语句 → 赋值语句 | 条件语句 | 循环语句 赋值语句 → 变量 := 表达式 条件语句 → if 条件 then ( 语句 | 程序 ) 循环语句 → while 条件 do ( 语句 | 程序 ) 表达式 → 项 { + 项 | - 项 } 条件 → 表达式 关系符 表达式 关系符 → < | <> | <= | > | >= | = 项 → 因子 { * 因子 | / 因子 } 因子 → 变量 | 数字 | ( 表达式 ) 变量 → 标识符 一、 词法分析器 词法分析器的任务是清除源文件中多余的空格、换行、制表符等,识别文法符号。按顺序输出识别的标识符及其种别编号,供语法分析器调用。 代码如下: #include <stdio.h> #include <string.h> #include

词法分析器:代码注释

我的梦境 提交于 2020-01-04 23:54:55
前沿:词法分析器是将一段程序的代码按照类别分开. 一般来说是将关键字, 变量名 , 常数 运算符( + _ * / )和界符分类 词法分析算是编译的基础把 今天上编译原理的实验课, 看了看 老师给的代码 添加了一些注释 大致的流程是这样的: 规定关键字的符号是10 数字的符号是数字本身 + - * = 这些符号代码中的case里面有(分别是13 14 ...),可以看懂的 首先, 把程序存到制定的内存区域, 这里是划出了一个连续的空间(放到字符数组); 然后再按字节读取里面的内容 , 当读到空格(" ")或者是换行符号(\n)的时候,就默认是一个单词啦,() 把这个单词放进一个另外一个数组里面,美其名曰token[]; 获得这个token之后 , 首先判断token中的每一个字符是不是属于a-z的字符里面(需要一个while循环遍历) 如果在读取的字符不是一个字母, 那在看看是不是数字(0-9),如果是的话,那就写成相应的标识符 如果读取的是+ 那么将syn(表示代号)为13 每次识别出来之后,都以 ("syn " , string )的形式输出 /**C语言的词法分析 **/ #include<stdio.h> #include<string.h> /** 程序规定: 1、关键字:"function","if","then","while","do","endfunc"; 2

词法分析器与正规式

大城市里の小女人 提交于 2020-01-04 23:54:21
词法分析器 词法分析器是一个程序,它的任务是从源程序中提取单词。比如从源程序中提取出保留字,标识符,常数,运算符等单词符号。 词法分析器的结果是输出单词(token),通常是二元式(单词种别,单词自身的值)。 单词种别的划分,是如何设计编译器层面上的事情。可以将所有的保留字视为一种,也可以将每个保留字都视为一种。不过通常是将每种单词视为一个整数码,这样方便处理。 单词自身的值,如果一个单词种别只包含一个单词, 那么其种别编码就是其自身的值。 对于标识符和,其在符号表的入口指针作为它自身的值。 状态转换图 状态转换图对于单词的识别是可行的。只要构造出相应语言的单词的状态转换图,那么单词的识别是非常容易的。 正规式 可以将状态转换图的概念加以形式化,那么就是正规式。正规式用数学语言描述了状态转换图。可以用程序对正规式构造相应的状态转换图。 那么只要将状态图加以形式化,那么就可以自动生成词法分析器。 来源: https://www.cnblogs.com/beMaster/p/5066373.html

词法分析中的“贪心算法”(读《C陷阱与缺陷》)

六眼飞鱼酱① 提交于 2019-12-25 01:38:21
1、一些专业名词的定义 符号:关键字+标志符+运算符 词法分析器:编译器中负责将程序分解为一个一个符号的部分,一般称为词法分析器。 符号之间的空白(空格符、制表符、换行符)被忽略。 因此代码1和代码2是等效的 代码1: 1 if (x > y) big = x 代码2: 1 i 2 f 3 ( 4 x 5 > 6 y 7 ) 8 b 9 i 10 g 11 = 12 x C语言中某些符号: 例1:/ 、*、= 特点:只有一个字符长。称为单字符符号 例2: /* 、==、以及标识符,包括了多个字符,称为多字符符号 简单的来说词法分析中的“贪心算法”就是,当C编译器读取了一个字符,他会继续读取连续最大范围内与它组成符号的其他字符。如果不能组成符,则停止。 规则:每个符号尽可能包含多的字符,编译器从左至右一个字符一个字符读入,如果该字符可能组成一个符号,那么再读入下一个字符,再判断已经读入的两个字符组成的字符串是否可能是一个字符的组成部分,如果可能,继续读入下一个字符,重复上述循环且判断,直到读入的字符组成的字符串已不再可能组成一个有意义的的符号。 需要注意的是:除了字符串和字符常量,符号的中间不能嵌有空白(空白符、制表符、换行符),例如 == 和 = = 是两个符号 代码3: 1 y=x /* p 代码4: 1 y=x/ *p 代码3则表示 /* 后面的全被注释,直到匹配到右注释符号

词法分析——贪心法

冷暖自知 提交于 2019-12-25 01:36:31
1.提出问题   C语言的某些符号,例如 /、* 和 = ,只有一个字符长,称为 单字符符号 。   而C语言中的其他符号,例如 /* 和 == ,以及标识符,包括了多个字符,称为 多字符符号   当C编译器读入一个字符 ' / ' 后又跟了一个字符 ' * ',那么编译器就必须做出判断:是将其作为两个分别的符号对待,还是合起来作为一个符号对待。 2.解决问题   C语言对这类问题的规则可以归纳为: 每一个符号应该包含尽可能多的字符 。这个处理策略有时被称为“ 贪心法 ”,或者“大嘴法”。   详细说来就是:编译器将程序分解成符号的方法是,从左到右一个字符一个字符地读入,如果该字符可能组成一个符号,那么再读入下一个字符,判断已经读入的两个字符组成的字符串是否可能是一个符号的组成部分;如果可能,继续读入下一个字符,重复上述判断,直到读入的字符组成的字符串已经不可能组成一个有意义的符号。   标准表述: 如果(编译器的)输入流截至至某个字符之前都已经被分解为一个个符号,那么下一个符号将包括从该字符之后可能组成一个符号的最长字符串 。 3.注意   除了字符串与字符常量,符号的中间不能嵌有空白(空格符、制表符和换行符)。   例如:== 和 = = 不同;a---b 和 a-- -b相同,和 a- --b不同。   这些类似 准二义性(near-ambiguity)问题 。 来源:

词法分析

丶灬走出姿态 提交于 2019-12-18 16:40:30
词法分析器 定义: 词法分析器的功能输入源程序,按照构词规则分解成一系列单词符号。单词是语言中具有独立意义的最小单位,包括关键字、标识符、运算符、界符和常量等 (1) 关键字 是由程序语言定义的具有固定意义的标识符。例如,Pascal 中的begin,end,if,while都是保留字。这些字通常不用作一般标识符。 (2) 标识符 用来表示各种名字,如变量名,数组名,过程名等等。 (3) 常数 常数的类型一般有整型、实型、布尔型、文字型等。 (4) 运算符 如+、-、*、/等等。 (5) 界符 如逗号、分号、括号、等等。 输出: 词法分析器所输出单词符号常常表示成如下的二元式: (单词种别,单词符号的属性值) 单词种别通常用整数编码。标识符一般统归为一种。常数则宜按类型(整、实、布尔等)分种。关键字可将其全体视为一种。运算符可采用一符一种的方法。界符一般用一符一种的方法。对于每个单词符号,除了给出了种别编码之外,还应给出有关单词符号的属性信息。单词符号的属性是指单词符号的特性或特征。 示例: 比如如下的代码段: while(i>=j) i-- 经词法分析器处理后,它将被转为如下的单词符号序列: <while, _> <(, _> <id, 指向i的符号表项的指针> <>=, _> <id, 指向j的符号表项的指针> <), _> <id, 指向i的符号表项的指针> <--, _>

从hello world 说程序运行机制

我们两清 提交于 2019-12-18 15:41:00
转自: http://www.cnblogs.com/yanlingyin/archive/2012/03/05/2379199.html 开篇 编译,简单的说,就是把源程序转换为可执行程序。 从hello world 说程序运行机制 里面简单的说明了程序运行的过程,以及一个程序是如何一步步变成可执行文件的。在这个过程中,编译器做了很多重要的工作。对底层该兴趣的我,自然的,也就迫切想搞清楚编译的内部实现,也就是编译的原理。 这篇文章主要说的是编译器前端,词法分析器的原理,最后会给出一个词法分析器的简单实现。 介绍 编译简单的说,就是把源程序转化为另一种形式的程序,而其中关键的部分就是理解源程序所要表达的意思,才能转化为另一种源程序。 可以用一个比喻来说明问题:人A和人B想要交谈,但是他们都不知道彼此的语言,这就需要一个翻译C,同时懂得A和B的语言。有了C做中间层,A和B才能正常交流。C的作用就有点像编译器,它必须能理解源程序所要表达的意思,才能把信息传递给另一个。 编译器也一样,它的输入是语言的源文件(一般可以是文本文件)对于输入的文件,首先要分离出这个输入文件的每个元素(关键字、变量、符号、、) 然后根据语言的文法,分析这些元素的组合是否合法,以及这些组合所表达的意思。 程序设计语言和自然语言不一样,都是用符号来描述,每个特定的符号表示特定的意思,而且程序设计语言是上下文无关的

Swift Playground词法分析器DEMO

不打扰是莪最后的温柔 提交于 2019-12-10 15:52:06
正在看极客时间宫文学老师的 编译原理之美 ,用swift playground写了一个第二课“int age >= 45”的词法解析DEMO 为了保持原课程代码,DEMO用了顺序结构,看起来有点散乱😂,后面我再抽时间优化一下 //识别:“int age >= 45” import Foundation enum DfaState: String { case Initial = "Initial" case Id = "Id" case IntLiteral = "IntLiteral" case GT = "GT" case GE = "GE" } enum TokenType: String { case Identifier = "Identifier" case IntLiteral = "IntLiteral" case GT = "GT" case GE = "GE" } func isAlpha(_ ch:Character) -> Bool { return ch.isLetter } func isDigit(_ ch:Character) -> Bool { return ch.isNumber } class Token { var type: TokenType? var tokenText: String = "" } var newState =

关于flex/bison 语法分析的问题

你说的曾经没有我的故事 提交于 2019-12-09 13:32:46
关于flex/bison 语法分析的问题 在进行语法分析的时候,发现在flex词法分析中分析过的词传不过来,之后查了网上说要用yylval参数传值,但是我需要传的参数种类很多,于是我申明了一个union,并给YYSTYPE定义为这个union(YYSTPE是yylval的类型),但是发现报错如下: union中的类型没有找到,一直以为是编译器出了问题,但是查看bison生成的头文件发现了事实的真相。 bison中为了满足各个符号不同的语义值的类型可以定义 %union{ …… } 如图: 其中YYSTYPE的定义就来源于这个,而不能自己在flex文件中定义union,然后赋值给YYSTYPE 如果需要用到yylval直接引用头文件 #include "xxx.tab.h" 即可 件 #include "xxx.tab.h" 即可 来源: CSDN 作者: AnnaZhan 链接: https://blog.csdn.net/AnnaZhan/article/details/103456037