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

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

《自制编程语言》学习记录,内容基本是摘抄原书其实原书并不是从头讲怎么写一个计算器的,而是上来就给了代码,对着代码讲解。计算器代码的名字为mycalc,内部完全使用double进行运算。...因此在语义分析阶段,会检查程序中是否含有语法正确但是存在逻辑问题的错误。...就是能根据语法规则自动生成解析器的程序 yacc和lex在mac上已经预装。...比如C语言的if语句,就有很明显的语法模糊问题: if (a == 0) if (b== 0) printf(在这里a和b都为0n); else printf(这里a非...后续会不借助jacc和lex重新制作一个计算器。本文结束。 本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议 ----

4.6K10

栈的实现和括号匹配问题

\n", STTop(&s)); STPop(&s); } STDestroy(&s); return 0; } 注意:出栈可以边入边出,入栈1 2 3 4,出栈不一定是4 3 2 1 3.括号匹配问题...OJ链接:有效的括号 左括号必须和右括号相匹配必须是成对出现的,如果匹配就返回true否则返回false,这道题乍一看不好判断,其实我们可以用栈来解决,栈是后进先出的原则,如果是左括号就入栈,如果是右括号就出栈顶的左括号进行判断是否匹配...,此时的栈里面都是左括号,这里我们的需求是后进先出,我们要让右括号和后进的左括号相匹配,这不就完美的匹配了后进先出。...它们常用于实现函数调用(函数调用栈)、表达式求值(算术表达式的括号匹配和计算顺序)、内存分配(如自动变量存储)等。...这些实现方式各有优缺点,具体选择取决于应用场景和性能需求。在实际应用中,栈的使用通常需要与其他数据结构和算法相结合,以实现复杂的程序逻辑和功能。

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

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

    要回答这些问题,就需要了解这篇文章中介绍的各种概念。这篇文章通过实现中文计算器方式,来介绍解释器或编译器中的各种概念。 基本概念 如何执行一个字符串 1+1 呢?...Lex 常常与 yacc 语法分析器产生程序一起使用。 yacc(Yet Another Compiler Compiler),是Unix/Linux上一个用来生成编译器的编译器(编译器代码生成器)。...这个中文计算器和普通的计算器非常相似,只是不使用 0123456789 而是 零壹贰叁肆伍陆柒捌玖拾佰仟万亿,不使用 +-*/(),而是 加 减 乘 除 左括号 右括号。..."右括号"}; 中文计算器中一共有上面 7 种类型的 token。...可以发现字符串中的括号并没有与之对应的节点,而是使用树的层级来描述对应的优先级。 中文计算器语法 中文计算器的语法可以用下面 EBNF 来表示。

    78610

    懂前端的你也可以轻松定义自己业务的DSL

    jison有很多demo可以供参考,比如 写一个计算器 https://gerhobbelt.github.io/jison/try/图片要实现这个计算器,你的代码不再是手写解析算术表达式,手写语法树解析...数字是由一个或多个数字(digit)和一个可选的小数点以及一个可选的指数部分组成。...终结符号集:数字(0-9)、加号(+)、减号(-)、左括号(()、右括号())2. 非终结符号集:表达式(E)、项(T)、因子(F)3....DSL擅长解决哪些领域的问题DSL(领域特定语言)擅长解决领域特定问题,即在特定领域中使用的编程语言。以下是一些DSL可以解决的问题的例子:1....Regex:正则表达式是一种DSL,用于匹配和操作文本。它在许多编程语言中都得到了广泛的应用,可以用于文本搜索,替换和解析。DSL可以用于在特定领域中更有效地解决问题,提高开发效率和代码质量。

    2.5K41

    6÷2(1+2)到底等于1还是9?

    额外的括号(方括号)消除了歧义,这些表达式定义明确。大多数其他的常见的数学问题,比如 都有明确的定义,有一个正确的答案和一个(或多个)常见的错误答案。...但是计算算式 6÷2(1+2)的值是一种习惯问题。答案1和9都不对:这取决于你从数学老师那里学到的是什么。...数值运算的顺序由各种四则混合运算法则PEMDAS、BODMAS、BIDMAS和BEDMAS给出: P(或B):先计算括号(方括号)内表达式的值; E(或O或I):接下来计算指数(阶/指数); MD(或DM...对两者的支持 事实上,谷歌、Wolfram和许多计算器的答案都是9。这里计算器的答案当然是由他们的输入法决定的。显然,计算器并不是四则混合运算法则悖论的最佳判断工具。...希望在阅读了本文之后,您能够满意地理解一个看起来如此基础的问题是如何遗留下来的。在现实生活中,你应该使用更多的括号,避免歧义。

    74510

    javacc功能一览

    1.编译原理中常见的解析器LL和LR的对比;2.javacc的特征;3.如何在java ide中进行javacc的开发;4.通过演示一个javacc计算器的例子让你对javacc有更多了解(只是一个简单地演示...javacc特征 •JavaCC生成自上而下的(递归下降[1])解析器,而不是类似YACC[2]的工具生成的自下而上的解析器。尽管不允许左递归[3],这允许使用更通用的语法。...对于自上而下的解析器而言,Shift-reduce和reduce-reduce冲突不是问题。...•JavaCC版本包含各种示例,包括Java和HTML语法。这些示例及其文档是熟悉JavaCC的好方法。 示例 本示例识别匹配的括号,后跟零个或多个行终止符,然后是文件结尾。...计算器示例 Calculator.jj的详细代码如下: PARSER_BEGIN(Calculator) package com.test.parser.javacc.calc; import java.io

    2K10

    随便聊聊(模糊泊车相关、李雅普指数计算和常见的matlab使用问题)

    这么多来要这个仿真模型的,文件传送门: Matlab 模糊控制 车辆泊车 案例分享 对了,还有个同学不知道这个m文件怎么用, 文章里面的代码复制到matlab,编辑一个m文件就可以了,fis文件和保存的...m文件注意都要放在当前文件夹下面,不然就会报错 就类似于这种 然后又有几个同学咨询是关于李雅普指数的,这个晚上看到一个知乎的文章,觉得写的很好,给作者留言申请转载,暂未获得作者回复,这儿直接给出网址...(https://zhuanlan.zhihu.com/p/58738073)感兴趣的同学自己去看看哦 之前写过的一些关于李雅普指数的文章: Matlab求解混沌系统最大李雅普诺夫指数 最后是几个比较多咨询的问题...你要把对应的代码、模型之类的文件放在这个文件夹下面 上面fis报错也是这个同一个问题 3、simulink文件不能打开 解决方案:这是因为你的文件名字不对,simulink的文件名字不能有括号之类的符号

    44820

    Flex & Bison 开始

    Knuth 所研究的语法分析理论(因此 yacc 十分可靠)和方便的输入语法。这使得 yacc 在 Unix 用户中非常流行,尽管当时 Unix 所遵循的受限版权使它只能够被使用在学术界和贝尔系统里。...由于这个版本比贝尔实验室的 yacc 更快并且使用了灵活的伯克利许可证,它很快成为最流行的 yacc。...由于它比 AT&T 的 lex 更快速和可靠,并且就像伯克利的 yacc 那样基于伯克利许可证,它最终也超越了原来的 lex。...安装 大多数 Linux 和 BSD 系统自带 flex 和 bison 作为系统的基础部分。如果你的系统没有包含它们,安装它们也很容易。...范例指导了我们如何使用 Flex & Bison 开发一个计算器,并能支持变量、过程、循环和条件表达式,有内置函数,也支持用户自定义函数。

    1.6K20

    【Python神器】使用lex进行规则解释

    使用lex进行解释 ---- 同事们好像觉得这个功能实现很难,没什么信心,其实只要理解其中的逻辑,并不复杂,就算不借助工具也能实现,单单用正则和循环也能解决。...不过,使用神器lex显然是更好的解决方案(lex经常和yacc搭配使用,不过我们的需求比较简单,并不需要用到yacc)。...import ply.lex as lex # List of token names. tokens = ( 'KEYWORD', # 关键词 'LPAREN', # 左括号...lex与yacc ---- 有了这两个神器,想实现一门简单的语言也是不难的。而且,理解了这两个工具,非常有助于理解编程语言本身,可谓大有益处。 程序员还是要保持好奇心。...备注: ply是Python Lex Yacc的缩写,官方文档:http://www.dabeaz.com/ply/ply.html

    1.3K10

    Python 之父的解析器系列之六:给 PEG 语法添加动作

    这对于新的解析器来说是件好事,但对于我来说却是个不小的挑战:需要一定的时间和精力,而我对解析器的知识极为欠缺,也造成了翻译过程的不顺畅。...Github 开源,项目地址:https://github.com/chinesehuazhou/guido_blog_translation) 许多语法都有支持给规则添加动作的约定,通常是 { 花括号...一个永恒的问题是何时执行动作块。在 Yacc / Bison 中,因为没有回溯,一旦规则被解析器识别到,就会执行动作块。...关于 {花括号} 里面的内容,传统上是使用 C 语言,它约定用 $ 符号来引用已识别的备选项(例如,$1 引用第一个条目),并赋值给 $$ 以指示动作的结果。...举个例子,这是一个简单计算器,可作加减法: start: expr NEWLINE { expr } expr: expr '+' term { expr + term } | expr '-'

    56720

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

    右边的图是一个简单的编译流程图,在早期,编写编译器相当耗时,直到Lex和YACC的诞生,有了它们,开发者只需要关注如何设计词法和语法规则,剩下的解析器代码都由它们来生成处理,大大提高了程序编译解析器开发的效率...我们的议题重点关注Lex&YACC和LEMON Parser Generator。 在Lex YACC解析器中,生成解析器的流程如右图所示。...三、如何人工挖掘语法规则的漏洞 首先是Lex和YACC历史漏洞不多,但词法/语法规则是由开发者定义的,虽然Lex 和YACC的代码不多,漏洞较少,但规则就好比我们开发的插件,如果插件有问题,这个软件也存在安全风险...接下来,我们来看一下Lex和YACC的攻击模型。 正如右图所示,黄色部分表示可能被攻击的攻击面,分别对应四个处理程序(Lex,YACC,yylex,yyparse)。...不过这里要说明一下,因为它是从左往右一个token 一个token扫描的,所以我们最简PoC不写右括号也没事,因为在到右括号之前代码就出问题了。

    99840

    函数指针数组的概念和应用

    函数指数组是存放函数指针的数组 int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int...书写小技巧: 我们书写函数指针数组时,先写上函数指针的形式,接着在名字后面加上数组的 [ ] 方括号,就可以完成对函数指针数组形式的书写。 有什么用? 我们来模拟实现一个计算器。...2、未来我们想在这个计算器里增加其他的运算法则,case语句会变的越来越多,里面的代码冗余现象也会越来越严重。 那如何去解决上述问题呢 那就需要我们的函数指针数组出马了!...\n"); else printf("输入非法,请重新输入\n"); } while (input); return 0; } 注意当我们调用函数指针数组时,可以直接写数组名,然后后面括号写函数的参数...return 0; } 小技巧: 指针把*和名字去掉,剩下的就是指针指向的对象 数组把数组名和 [ ] 去掉,剩下的就是存放在数组中的类型。

    7910

    编译原理初学者入门指南

    最新(其实是两年前了)的进展是 BERT 模型和衍生出来的许多研究上下文关系的方法,现在的 NLP 技术已经可以做阅读理解问题了。 此外,DSL 和 GPL 的共同点也止步于此。...2.3 别慌:英文缩写都是纸老虎 现在我们知道了事情的来龙去脉,也就明白了开头的需求属于哪种问题。...对工程师来说,解决问题的第一步就是先知道你面对的是什么问题:使用编译原理的知识来解析开头的表达式,相当于定义一个简陋的 DSL 语言,并编写词法解析器和语法解析器(lexer & parser)来将其转换成...你可以选择自己编写 lexer 和 parser,也可以选择通过定义 yacc 文件的方式让工具自动生成。...3.5 参考工程 goyacc 的示例工程不多,不推荐用 yacc 实现计算器的例子,参考性比较差。

    2.4K21

    TiDB SQL Parser 的实现

    Lex & Yacc 介绍 Lex & Yacc 是用来生成词法分析器和语法分析器的工具,它们的出现简化了编译器的编写。...Lex & Yacc 分别是由贝尔实验室的Mike Lesk 和 Stephen C. Johnson在1975年发布。...从上面的流程可以看出,用户需要分别为Lex提供patterns的定义,为 Yacc 提供语法规则文件,Lex & Yacc 根据用户提供的输入文件,生成符合他们需求的词法分析器和语法分析器。...产生式右侧的大括号中定义了该规则关联的动作,例如: expr: expr '*' expr { $$ = $1 * $3; } 我们将堆栈中匹配该产生式右侧的项替换为产生式左侧的非终结符...goyacc 简介 goyacc 是golang版的 Yacc。和 Yacc的功能一样,goyacc 根据输入的语法规则文件,生成该语法规则的go语言版解析器。

    61210

    TiDB 源码阅读系列文章(五)TiDB SQL Parser 的实现

    Lex & Yacc 介绍 Lex & Yacc 是用来生成词法分析器和语法分析器的工具,它们的出现简化了编译器的编写。...Lex & Yacc 分别是由贝尔实验室的 Mike Lesk 和 Stephen C. Johnson 在 1975 年发布。...从上面的流程可以看出,用户需要分别为 Lex 提供 patterns 的定义,为 Yacc 提供语法规则文件,Lex & Yacc 根据用户提供的输入文件,生成符合他们需求的词法分析器和语法分析器。...产生式右侧的大括号中定义了该规则关联的动作,例如: expr: expr '*' expr { $$ = $1 * $3; } 我们将堆栈中匹配该产生式右侧的项替换为产生式左侧的非终结符...goyacc 简介 goyacc 是 golang 版的 Yacc。和 Yacc 的功能一样,goyacc 根据输入的语法规则文件,生成该语法规则的 go 语言版解析器。

    4.6K100

    goyacc 实战

    的过程,这个过程一般比较简单,可以使用 lex, flex 之类的工具,也可以完全手写 语法解析时将 token 组合解析成语法树的过程,对于比较复杂的 dsl 设计,这个过程可能比较复杂,可以借助如 yacc...这样的工具,但是为了追求效率,也可以完全手写(promql 就是手写,如果是手写,没有太大必要把词解析和语法解析两者分割得太清楚) 执行我们只看即时执行的情况,一般来说可以对上一步的语法树直接执行,也可以做进一步编译...$3) } | expr2 '/' expr3 { $$ = $1.Quo($1, $3) } expr3: NUM | '(' expr ')' { $$ = $2 } 实战:计算器...这个例子时上面的示例的完整版本,来自 go 官方, 本质是实现了一个大数的计算器,支持 "+", "-", "*", "/", "(", ")", 值得注意的是 expr 定义了几种,里面蕴含了优先级关系...the cell under the pointer is nonzero 代码在这里 我们除了 lexer.go parser.y 之外还写了一个 env.go, 这是执行使用的结构体,目的是优化和执行代码

    5.3K60

    回溯算法最佳实践:合法括号生成

    对于括号合法性的判断,主要是借助「栈」这种数据结构,而对于括号的生成,一般都要利用回溯递归的思想,比如前文 如何拆解复杂问题:实现一个计算器 就用递归处理了括号优先级的问题。...反之,比如这个括号组合))((,前几个子串都是右括号多于左括号,显然不是合法的括号组合。 下面就来手把手实践一下回溯算法框架。 回溯算法思路 明白了合法括号的性质,如何把这道题和回溯算法扯上关系呢?...算法输入一个整数n,让你计算 n对儿括号能组成几种合法的括号组合,可以改写成如下问题: 现在有2n个位置,每个位置可以放置字符(或者),组成的所有括号组合中,有多少个是合法的?...其实回溯算法和动态规划的本质都是穷举,只不过动态规划存在「重叠子问题」可以优化,而回溯算法不存在而已。...left和right的组合好办,他俩取值就是 0~n 嘛,组合起来也就n^2种而已;这个track的长度虽然取在 0~2n,但对于每一个长度,它还有指数级的括号组合,这个是不好算的。

    78510
    领券