首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Yacc 与 Lex 快速入门(词法分析和语法分析)

另一方面,如果没有可以匹配的常规表达式,将会停止进一步的处理,Lex 将显示一个错误消息。 Lex 和 C 是强耦合的。...在看 Yacc 程序的每一段时,我们将为我们的例子编写一个语法文件。 C 与 Yacc声明 C 声明可能会定义动作中使用的类型和变量,以及宏。 还可以包含头文件。...每个 Yacc 声明声明了终端符号和非终端符号(标记)的名称,还可能描述操作符优先级和针对不同符号的数据类型。 lexer (Lex) 一般返回这些标记。...所有这些标记都必须在 Yacc 声明中进行说明。 文件解析的例子我们感兴趣的是这些标记:name, equal sign, 和 age。Name 是一个完全由字符组成的值。 Age 是数字。...命令行的其他常用选项 '-d' ,'--defines' : 编写额外的输出文件,它们包含这些宏定义:语法定义的标记类型名称,语义的取值类型 YYSTYPE, 以及一些外部变量声明

5.1K20

借助yacc和lex自制计算器——《自制编程语言》一

1.1.3 语义分析     经过语法分析生成的分析树,并不包含数据类型等语义信息。因此语义分析阶段,会检查程序是否含有语法正确但是存在逻辑问题的错误。...第6行到第9行声明了记号以及非终结符的类型。非终结符是由多个记号共同构成,即代码证的line_list、line、expression、term这些部分。...这种记号称作终结符 第10行到第11行是记号的声明。myclac所用到的记号类型都在这里定义。...这里的double_value是来自上面代码%union集合的一个成员名(第8行)。 第12行声明了非终结符的类型。 第13行的%%是分界,之后的是规则区块。...所谓冲突,就是遇到语法模糊不清的地方时,yacc报出呃错误

4.4K10
您找到你想要的搜索结果了吗?
是的
没有找到

【Python】Ply 简介

int(t.value) return t 正则表达式函数的文档字符串中指定, 参数固定是 lex.LexToken 的实例,它包含四个基本属性: type: 类型,就是 tokens...Token discarded 或者,您可以token声明包含前缀“ignore_”,以强制忽略token。例如: ` t_ignore_COMMENT = r'#.*' 2....,当词法分析出现错误时,你应该明确的告诉用户哪儿错了,使用 t_error 来声明错误提示信息,如下: def t_error(t): print(f"Illegal character '...TOKEN 优先级从小到大排列,上面的表达式声明了加减的优先级小于乘除,且它们都是左关联的。...这些定义将被应用于每条语法规则,LR 语法,语法规则的优先级总是由其最右面的富豪的优先级决定的。

2.5K30

thriftpy+ply源码分析

lex工具会帮我们生成一个yylex函数,yacc通过调用这个函数来得知拿到的token是什么类型的,但是token的类型yacc定义的。...刚才说完lex了,那么yacc呢,教科书上把yacc做的工作叫做syntactic analysis。这次我们翻译没有直译做句法分析,而是叫语法分析,这个翻译能好一点,意思也基本上比较清楚。...使用lex和yacc我们要做那几件事情? 定义各种token类型。他们.y定义,这些token既会被lex使用到,也会被.y文件的BNF使用到。 写词汇分析代码。...这部分代码.l文件(就是lex的输入文件)。这块的定义方式是:正则表达式-->对应操作。...如果和yacc一起来使用的话,对应的操作通常是返回一个token类型,这个token的类型要在yacc中提前定义好。 写BNF。这些东西定义了语言的规约方式。

64310

CSS大会 | 打破常“规”:挖掘语法解析器规则漏洞

我们的议题重点关注Lex&YACC和LEMON Parser Generator。 Lex YACC解析器,生成解析器的流程如右图所示。...错误使用输入的处理函数,可能会把类型转错传递给语法解析器。...但是这个过程没有判断主键是否重复;这样,里面就有两个主键,但是第二个主键添加的时候,因为列表里已经有一个同样的主键,于是它虽然成了主键,但是却指向一个空位置。...1.避免类型混用 规则定义,可能存在大量的类型转换(显式的和隐式的),需要对每种情况都做好单元测试,以防漏掉某个规则产生混用。...3.检查边界值 规则定义也存在类似边界情况的问题,比如某些值未被规则包括,或者某些特殊情况会产生异常问题,这些都要考虑在内。 4.检查不正确的值传递 嵌套调用时,值可能会以不同类型的状态传递。

95840

编译入门 - 从零实现中文计算器

要回答这些问题,就需要了解这篇文章中介绍的各种概念。这篇文章通过实现中文计算器方式,来介绍解释器或编译器的各种概念。 基本概念 如何执行一个字符串 1+1 呢?... JS ,我们可以直接执行 eval('1+1') 就行了,这将会输出 2。如果不能使用 eval 这些函数,那么如何执行这个字符串呢?如何自己实现一个 eval 函数?...GNU bison基本兼容Yacc,并做了一些改进。它一般与flex一起使用。 上面介绍了几个有名的工具,这些工具在其他语言中都有对应的类库,比如 JS 的 bison 叫 jison。...可以发现字符串的括号并没有与之对应的节点,而是使用树的层级来描述对应的优先级。 中文计算器语法 中文计算器的语法可以用下面 EBNF 来表示。...const NodeType = { BinOp: 0, UnaryOp: 1, Int: 2}; 我们首先声明 AST 节点的类型。一共只有 3 个,分别是的双向运算、单运算和整数节点。

73910

Delphi类型和引用

Delphi,一般私有变量字段都以 F打头。并且声明了一个构造CREATE,一个析构Destroy,一个过程Display,一个函数SetStr。另外还 明了一个属性Caption。...首先声明了一个类类型TClass,其中声明了一方法Method,然后就是方法Mehod的定义,方 法本身有两个参数,方法的执行体对类的字段的引用是直接的,不需要加引用限字符。...注意:尤其是熟悉C++的程序员要注意,C++,当您用一个类类型声明一个对象时,将自动调 用类的构造函数(这也是C++中一般不需要显式调用构造函数的原因),而在object Pascal,当您 明了一个类类型的变量...TClass类型的类,声明了一个字段FMyProperty(将私有字段标识符以F打头是 DELPHI程序员遵循的一个习惯,很多源代码可以看到这一点),它的数据类型是某种数据类型, 还声明了一个方法,...Protected部分声明的成员通常是方法,这样既可以派生类访问这些方法,又不必知道方法实现 的细节。

2.4K30

Postgresql源码(50)语法解析时关键字判定原理(函数名不能使用的关键字为例)

lex返回522后,yacc语法树没有匹配项了,返回错误。 [lex] NORMALIZE = 522 [yacc] if (!...core_yylex需要返回它遇到的标识符类型并将其值存储yylval这些标识符gram.y定义: gram.y %token ABORT_P ABSOLUTE_P ACCESS...这些标识符主要是给lex使用的,lex匹配到正则规则时,返回其中一个token。...但其实很多也不会触发冲突,为了使用这些关键字,gram.y文件后面专门定义了几组语法规则: unreserved_keyword:可以用于任意命名场景,如果新增的关键字不会引发shift/reduce...增加方法:先确定新增关键字会不会造成语法冲突歧义等,加到上面5个list,然后根据能否用于表名、列名、as等场景,kwlist增加即可。

73830

自制计算器——《自制编程语言》二

为了暂存数值,采用一个枚举类型LexerStatus*的全局变量status(第12行) LexerStatus枚举的定义lexicalanalyzer.h status的初始状态为INITIAL_STATUS...,当遇到0\~9的数字时,这些数字会被放入整数部分(此时状态为为IN_INT_PART_STATUS)(第59行)。...另外,像if、while这些保留字,比较简单的做法是先将其判别为标识符,之后再去对照表查找有没有相应的保留字。...C语言中,如果是通过typedef命名的一些类型,其标识符yacc(LALR(1)解析器)是无法解析的。...对此,C语言用了一个小诀窍,即在标识符作为类型名被声明的时候,会有语法分析器通知词法分析器,凡是遇到这个标识符,不要将其作为标识符,而作为类型名返回。

1.6K20

Oracle 数据库编程语言 PLSQL 的历史

尽管我不是 Matthew Symonds,也与 Softwar 这本书无关,但我依然花费了大量的精力研究 PL/SQL 的历史上。...画外音: 所有编程语言入门的第一个程序都是电脑上打印出“Hello World”。 很喜欢 Peter 这句话,自己是很难发现自己的一些错误。...还好 PL/SQL 第一个版本没有实现完全,因为数据库团队和 PL/SQL 团队都互相学习到了许多东西。每个团队都从另一个团队中注意到其它团队的问题。”...同样,当 YACC 认为它已经解析了 island grammar 时,它必须通知词法分析器它应该将其状态切换回宿主语言。尽管这些都可以使用 YACC,但实现所有的语言语法是非常痛苦的一件事。...SLAX 是 Segmented Language YACC 的意思。虽然 SLAX 与 YACC 没有共同的代码,Terry 依然决定向 YACC 表示敬意,因此命名为 SLAX。

1.5K20

前端报错 TypeError: a.slice is not a function 的原因与解决方案

然而,报错信息,提示 a.slice is not a function。这意味着 a 这个变量并没有 slice 方法。那么,为什么会出现这个错误呢?造成该错误的主要原因有以下几种:1....例如,如果我们期望 a 是一个数组,但我们却将一个数字赋值给了 a,那么 a 就变成了一个数字类型的变量,而数字类型没有 slice 方法。...例如,如果我们声明了一个变量 a,但在调用 slice 方法之前并未给它赋值,那么 a 的值将是 undefined,而 undefined 并没有 slice 方法。3....JavaScript 基本数据类型的限制 JavaScript ,除了数组和字符串,其他基本数据类型没有 slice 方法的。例如,数字类型、布尔类型和对象类型没有定义 slice 方法。...变量定义与赋值如果我们调用 slice 方法之前声明了变量 a,需要确保使用之前对其进行初始化赋值。有时,我们可能忘记对变量赋值,或者通过某些异步操作获取变量的值。

2.1K10

好的编程语言具备哪些特性?

这些都是无聊的答案,在这篇文章,我们寻求完美。 安全性很重要。生成的程序应该以可预测的方式运行,最好是无错误的。...它说明了这样一个观点:我们并不总是认可最好的产品,有可能完美的语言已经被创造出来,但我们并没有使用它。...这很有趣,但我真的没有任何理由用它来做任何实质性的事情。括号太多了,我没有任何顿悟。现在我探索 Shen,它有一些非常好的语法特性,嵌入式 Prolog 和一个可选的基于顺序逻辑的类型系统。...我喜欢从一个解决方案声明的方式创建函数图。但我讨厌当出了问题的时候,我不知道问题在哪里。...我认为 Java 的一个错误是它没有简单数据对象的记录或结构类型

2K10

Python 之父撰文回忆:为什么要创造 pgen 解析器?

之所以我要写自己的语法分析生成器,原因是当时这玩意(我熟悉的)相当稀少——基本上就是用 Yacc(有个 GNU 的重写版,叫作 Bison(译注:美洲野牛),但我不确定那时的自己是否知道);或者是自己手写一个...我曾在大学里用过 Yacc,从“龙书”熟悉了它的工作原理,但是出于某些原因,我并不喜欢它;IIRC 关于 LALR(1) 语法的局限性,我很难解释清楚。...至于词法分析器(lexer),我决定不使用生成器——我对 Lex 的评价要比 Yacc 低得多,因为尝试扫描超过 255 个字节的标记符时,我所熟悉的 Lex 版本会发生段错误(真实的!)。...如果我没记错,通过“正则表达式 -> NFA -> DFA”的转换过程,解析引擎(该网页前面的 syntacticAnalysis 函数)依然可以工作这些规则所派生的解析表上;我认为这里需要有不出现空白产物的诉求...正则表达式没有提高 LL(1) 的能力,更没有降低它的能力。

1.3K30

什么是好的编程语言?

这些都是无聊的答案,在这篇文章,我们寻求完美。 安全性很重要。生成的程序应该以可预测的方式运行,最好是无错误的。...它说明了这样一个观点:我们并不总是认可最好的产品,有可能完美的语言已经被创造出来,但我们并没有使用它。...这很有趣,但我真的没有任何理由用它来做任何实质性的事情。括号太多了,我没有任何顿悟。现在我探索 Shen,它有一些非常好的语法特性,嵌入式 Prolog 和一个可选的基于顺序逻辑的类型系统。...我喜欢从一个解决方案声明的方式创建函数图。但我讨厌当出了问题的时候,我不知道问题在哪里。...我认为 Java 的一个错误是它没有简单数据对象的记录或结构类型

2.6K20

【初识Go】| Day6 数组、切片

/方式三 var arr3 = [5]int{3:10} 输出以上三个变量的值如下所示: arr1 [0 0 0 0 0] arr2 [1 2 3 4 5] arr3 [0 0 0 10 0] 方法一声明没有为其指定初值...1.指针数组 对于指针数组来说,就是:一个数组里面装的都是指针,go语言中数组默认是值传递的,所以如果我们函数修改传递过来的数组对原来的数组是没有影响的。...,所以test1函数复制的新数组的值仍然是这些指针指向的具体地址值,这时改变a1这块存储空间地址指向的值,那么原实参指向的值也会变为2,具体流程如下图所示。...{} //方法二 var s2 = []int{1, 2, 3} //方法三 var s3 = make([]int, 5) //方法四 var s4 = make([]int, 5, 10) 方法一声明了一个空切片...,方法二声明了一个长度为3的切片,方法三声明了一个长度为5的空切片,方法四声明了一个长度为5容量为10的切片。

46900
领券