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

手摸手实现一个编译器(上)

二者的区别主要有: 编译器将一个程序作为一个整体进行翻译,而解释器则是一行一行地翻译; 在编译器的情况下生成中间代码或目标代码。.../simple-arithmetics.pegjs 那么生成的解析器会以 middle 作为语法入口,我们测试一下: const { parse } = require('....如果想要达到我们的预期,比如 start-middle-end 顺序,那么我们可以加上 --allowed-start-rules 参数并且指定 start: pegjs --allowed-start-rules...--extra-options-file 如果参数太多,在 CLI 中输入确实很不方便,也不够直观。这时通过指定一个 JSON 格式的文件作为 peg.generate 参数。...总而言之,写一个编译器,无非就 3 件事: 基于输入字符串做解析表达式匹配(正则匹配); 基于生成的结果做转换; 输出结果; PEG.js 只是简化了我们去执行上述动作的流程。

75110

聊聊PegJS

它的语法对前端工程师很友好,只需要掌握基本的正则语法即可,并提供在线体验网址。下面是基于PegJS语法的一个官方示例,它的语法有这样两个特点: PegJS的语法由一组规则组成,从上至下进行解析。...,可以将文本中符合规则的字符,比如 (2+7)*8,进行解析和运算。...number = float / integer 为避免歧义,如果定义规则start = a / b,当输入即可以匹配a也可以匹配b,那么PegJS则优先使用a来进行解析。..."1", ",", "2" ] 这里对匹配到的结果返回的value做一个说明: 与文字字符串匹配的表达式会生成包含匹配文本的JavaScript字符串。...interface.png 最后,将struct规则和interface规则进行整合后,就可以得到一个简单的Pegjs语法的JCE解析器了。

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

    手摸手实现一个编译器(中)

    分析 基于上述需求,可以分析得到我们需要识别的词法跟语法: 正确识别组件的父子关系;在 vue2 的模板编译中,通过正则和栈去维护开始标签和结束标签的关系,没有接触过的童鞋可以前往模板编译 了解。...value(比如对象),期望能够表现得更好,而不是仅仅当作字符串处理; 组件名和属性名只能包含中文; 测试用例 我们习惯用单测去了解框架的最小最细粒度功能,梳理场景也一样可以用这个方法。...紧接着就是核心的规则定义: // 一个完整的模板定义 // ws 即空白符,开始标签前随便你输入几个空白字符 // StartTag,开始标签的匹配 // children: (Tag*) 很关键,很关键...// EndTag,结束标签的匹配 // 最后的 action 即处理函数很关键,拿到匹配信息你可以做任何的判断、格式化 // 比如这里的 start 和 end 标签的 tag 不一致即组件名不一致,...验证 最后,将上述规则生成编译器: npx pegjs -o zh-template-compiler.js src/zh-template-compiler.pegjs 文章开头的 生成的 AST

    58020

    Java中next()和nextLine()的区别(为什么nextLine()输入回车没显示)

    str无法接受任何字符串(在我们眼中宛如直接跳过了该条语句一样)。 这是为何呢?nextLine()不是接受字符串吗?怎么不执行呢?...二、原因分析: 这里就要详细讲一下nextLine()在接受键盘输入的注意事项了。 注意:nextLine() 会接收回车字符(包含空格和Tab键)。...随后执行下一条语句nextLine(),nextLine()会接受(不排斥不忽略)这个回车字符,并且使得语句直接结束(nextLine()以回车符为结束)。...解决方案1: 既然我们知道了nextLine()的特性,那么,我们可以在nextInt()语句后面再加上一句nextLine()语句,用于“吃”掉这个输入缓冲区的’\n’。...next()方法是不接受回车字符的(包含空格和Tab键)! 什么意思?

    99420

    Swift结果生成器:几个必备的知识点

    buildBlock(_:)方法类似于StringBuilder的入口点,它接受组件的可变参数,这意味着它可以是1个或多个字符串。...5 支持不同的数据类型 Supporting Different Data Types 在这个阶段,我们已经使StringBuilder非常灵活,它现在可以接受选择语句、for循环和可选绑定作为输入。...但是,有一个很大的限制:它只能支持字符串作为输入和输出数据类型。 幸运的是,支持各种输入和输出数据类型非常简单。我来教你怎么做。...(_ expression: Int) -> String { return "\(expression)" } 此buildExpression(_:)方法是可选的,它接受整型作为输入并返回字符串...现在不再接受String作为输入数据类型,而是接受Int作为输入数据类型。

    1.9K20

    scanf的一些技巧

    一、scanf和gets 1.不同点:   char string[50];   scanf("%s",string); //当遇到回车,空格和tab键会自动在字符串后面添加'\0',但是不能接受回车,...gets(string); //遇到回车认为输入结束,并用'\n'替代 '\0'.回车键不会留在输入缓冲区中 2.相同点:   字符串接受结束后自动加'\0'。...scanf()作单字符输入时规定只接收一个字符,但它却把回车符也作为字符对待的。...这就造成程序中只有一个输入字符的scanf()语句时,问题还不大,但如果后面还跟着第二个scanf()字符输入语句,这个scanf()就把前面输入的回车符当作输入字符了。...这就在输入逻辑上造成了混乱,达不到人们预期的愿望。有了这个空格,因为scanf()是跳过空格读字符的,就回避了这个问题。实践证明,这个空格放在%c后面也不能达到目的。应当说,这也是比较巧妙的应用!

    63620

    C++ Primer Plus 第02章 开始学习C++ 学习笔记

    函数体:指出函数应做什么的计算机指令。 在C++中,每条完整的指令叫做语句。所有的语句都是以 分号结束。...以行尾作为结束。 注释的作用:为程序提供解释说明,使得程序通俗易懂。 通常标识程序的一部分或者是标识代码的某个方面。 注意点:编译器不会运行,会直接忽略注释。...C++也可以识别C语言的注释 C语言风格的注释 多行注释:符号/*和 */ 之间,以 */ 作为注释的结束。 单行注释:以 双斜杠(//) 开始,行尾作为结束。...显示字符串时,在字符串中包含换行符,而不是在末尾添加endl,可减少输入量。...其他C++语句 3.1 cin 和cout cin 使用 >> 运算符从输入流中抽取字符。 可以将通过键盘输入的一列字符(即输入)转换为接收信息的变量能够接受的形式。

    74000

    计算机小白的成长历程——分支与循环(3)

    ,也就是我们自己输入字符,它会将输入的字符存起来,相当于scanf函数,如图所示; 程序运行后我们可以看到,窗口此时是需要我们输入内容的,和scanf函数一样,这时我们输入字符a; putchar——...: 可以看到\0的值为0,EOF的值为-1,\0是字符串的结束标志,EOF是文件的结束标志,两者作用的对象也不相同,一个作用于字符串,一个作用于文件。...有细心的朋友会注意到我们前面的附图中,EOF显示的是#define EOF (-1)根据我们之前学到的知识可以知道,EOF其实是#define定义的标识符常量,下面是我通过联机搜索到的内容: 第一个代码我理解的意思就是可以连续输入除了文件结束标志以外的字符...,这个意思是不是输入字符0~9外的其它字符都无法打印,只能打印0~9的字符,下面我们就来验证一下: 这里我们可以看到除了0~9的字符外,输入其它的字符都无法打印,所以我们可以下一个结论,这个代码是来打印数字字符的代码...今天的内容到这里就结束了,可能会有朋友有疑惑,我们本章说的是while语句,为什么结尾提到这两个代码?它是有什么用吗?这两个代码的具体作用,后面会随着我学习的深入,第一时间与大家分享。

    13120

    66. 精读《手写 SQL 编译器 - 语法分析》

    另外也有一些根据文法自动生成 parser 的库,比如兼容多语言的 antlr4 或者对 js 支持比较友好的 pegjs。...2 精读 递归下降可以理解为走多出口的迷宫: 我们先根据 SQL 语法构造一个迷宫,进迷宫的不是探险家,而是 SQL 语句,这个 SQL 语句会拿上一堆令牌(切分好的 Tokens,详情见 精读:词法分析...考虑上面最简单的语句 select a from b,显然无法胜任真正的 SQL 环境,比如 select [位置] from b 这个位置可以放置任意用逗号相连的字符串,我们如果将这种 SQL 展开描述...、 && 连接、tree 分支、ε 空字符串的产生式这四种基本用法,这是符合下面四个基本文法组合思想的: G ::= ε 空字符串产生式,对应 () => true,不消耗 Token,总是返回 true...SQL 语法解析就是一个走迷宫的过程,将 Token 从左到右逐个匹配,最终能找到一条路线完全贴合 Token,则 SQL 解析圆满结束,这个迷宫采用空字符串产生式、单词匹配、连接运算、并运算这四个基本文法组合就足以构成

    1.5K30

    【重学 MySQL】七十四、揭秘存储过程的强大功能与实战技巧

    参数列表: 存储过程可以接受参数,这些参数可以是输入(IN)、输出(OUT)或输入输出(INOUT)类型。 IN:表示输入参数,用于向存储过程传递数据。...INOUT:表示既可以作为输入也可以作为输出的参数。这意味着你可以在存储过程中读取和修改这些参数的值。 datatype:参数的数据类型,如INT、VARCHAR等。...例如,你可以将分隔符更改为//,然后在存储过程的定义中使用//作为结束符。定义完成后,再将分隔符改回分号。 编写存储过程并不是一件简单的事情,可能存储过程中需要复杂的 SQL 语句。...DELIMITER也可以指定其他符号作为结束符。 当使用DELIMITER命令时,应该避免使用反斜杠(‘\’)字符,因为反斜线是MySQL的转义字符。...我们可以使用以下语句来调用它: CALL GetAllStudents(); 再假设我们有一个名为GetStudentByID的存储过程,它接受一个输入参数student_id,用于根据学号查询学生的信息

    29210

    04-程序流程控制(中卷)

    以后可以是枚举 JDK7以后可以是字符串[n3] case:后面跟的是要和表达式进行比较的值 语句体:要执行的代码 break:表示中断,结束的意思,可以控制switch...break 可以省略,但是不要在前面的case中省略,否则会造成case贯穿问题,可以在default中省略 4)default的位置一定要在最后吗? 可以出现在switch语句任意位置。...问题2:多个case后面的值不能出现相同的 ? 问题3:default可以省略吗? [n4] 问题4:break可以省略吗?[n5] ? 问题5:default的位置一定要在最后吗?...(表达式是字符的情况) 3)键盘录入字符串,根据给定的字符串,来输出你选择的字符串是什么?...可以 long类型可以是switch的表达式吗? 不可以 String类型可以是switch的表达式吗?

    43340

    兼顾简约与逼格的EOF判定法

    刚刚看到的时候我一脸懵逼。 代码解析 我们知道,‘~’在c语言中的作用是按位取反,但while的接受的是布尔值啊?取反不应该使用逻辑取反符号‘!’吗? 不对不对,这里一定另有玄机。...scanf 返回值分析 众所周知:scanf返回值是成功实际接受到的参数数量,此时,我们只用scanf接收了一个参数,那么 scanf的返回值始终 <= 1。 这也就是这个语句的关键!...例如,在一个简单的数据收集程序中,用户可以不断地输入数字,直到输入一个特定的结束信号(比如非数字字符)。...测试和调试:在编写程序时,可能需要测试程序对不同输入的处理能力,这个循环可以用来模拟连续的输入测试。...需要注意的是,这个循环在读取失败时会立即结束,因此在使用时应该考虑到错误处理和用户输入验证的问题。

    8710

    面试 | 百度测试开发岗位面试题目回顾

    5、现场写一个代码,有两个字符串类型的数字,实现一个方法将它们进行相加,并返回相加后的数值。(要考虑数据的长度问题)6、如果是做功能测试,能接受吗?7、对工作上的压力怎么看待?8、性能测试用过吗?...一面题目 1、自我介绍一下2、说一下你们工作中的测试流程3、数据库熟吗?用过哪些数据库?索引会吗?事务了解吗?写一个 SQL 查询语句:给一个字段,对其进行从大到小排序,取前十行。...接着让我根据这个算法写测试用例,注意还有要考虑没有这些符号但有其他字符的情况,以及字符串为空的情况。最好用等价类法,因为细分的话可以写的测试用例太多了, 6、Linux 熟吗?一般都用到哪些命令?...对不起,这个我不清楚还有什么类型可以实现......然后面试官说,其实我出道题的意思呢,就是想让写个算法解决大数据相加的问题,所以输入的都是字符串类型,你再想想.........他说基本没有了...简直要把我吓坏了...然后又开始问下一题 6、对工作上的压力怎么看待?7、如果是做功能测试能接受吗?8、性能测试用过吗?什么情况下用的?主要测哪些方面?

    78111

    Python 函数库 APIs 编写指南

    避免麻烦的输入:    -  检查是否存在参数名歧义的情况。例如在 Scrapy 1.2 中,send 方法有一个to 参数,接收的是字符串列表。...如果用户传入一个字符串,这个方法就会遍历这个字符串,并将每个字符当做一个邮箱地址并发送邮件。在 Scrapy 1.3 中则修改了这个 Bug,修改后即可以接收字符串,也可以接收字符串列表。    ...目前的是最好的选择吗?    ...,使用 __repr__ 魔法方法     - 对于包含 打开-关闭 或者 开始-结束 这样的包含生命周期的问题,使用 with 语句     - 对于容易组合共同行为或者登记某些东西使用装饰器     ... 函数中接受 key参数作为等级高低计算函数以便计算列表的顺序。

    86700

    python函数

    在调用需要指定参数的函数时,只需要在调用语句函数名后面的括号中给定参数即可,比如: greet_user_name('mwang') 这个语句将字符串mwang作为参数传递给greet_user_name...,它可以接受0或多个实参。...计算多个数字之和 现在写一个程序,它可以读取用户输入的多个数字,并将其结果返回。它的大致流程如下: 程序开始。 显示欢迎信息。 读取用户输入。 对用户输入进行处理,并将其转化成数字。 求和。...get_numbers_str_list()不接收参数,它读取用户的输入的字符串,按空格分割字符串,将其保存在一个列表里,并返回该列表: def get_numbers_str_list ():...,这就是get_numbers_list()的作用,它接受一个列表作为参数,将列表中的值转换成数字,并返回该数字列表。

    92820

    Java IO流处理 面试题汇总

    java中的阻塞式方法是指在程序调用改方法时,必须等待输入数据可用或者检测到输入结束或者抛出异常,否则程序会一直停留在该语句上,不会执行下面的语句。比如read()和readLine()方法。...在应用中,经常要完全是字符的一段文本输出去或读进来,用字节流可以吗? 计算机中的一切最终都是二进制的字节形式存在。对于“中国”这些字符,首先要得到其对应的字节,然后将字节写入到输出流。...底层设备永远只接受字节数据,有时候要写字符串到底层设备,需要将字符串转成字节再进行写入。...字符流是字节流的包装,字符流则是直接接受字符串,它内部将串转成字节,再写入底层设备,这为我们向IO设别写入或读取字符串提供了一点点方便。...2.Charset字符集编码解码解决方案 3.Channel一个新的原始 I/O抽象,用于读写Buffer类型,通道可以认为是一种连接,可以是到特定设备,程序或者是网络的连接。

    60220

    Python流程控制语句

    一、分支结构 (一)单分支语句 只有 if 子句,但注意分支条件后的冒号(:) 如果分支只有一条语句,则可以写在一行上; 如果分支有多条语句,需要写成缩进的语句块。...(输入0退出):")) print("游戏结束,你猜中了{}次".format(count)) 说明:①要把正常时不可能取到的值作为哨兵值。...②一定要在循环开始前对哨兵变量进行初始化,初始值需要根据情况而定,例如在处理字符串的问题中可以是空字符串。 ③循环体中一定有改变哨兵变量的语句,否则就会死循环。...continue语句是提前结束本次循环(即跳过continue语句后的其他语句)而马上开始本层的下一次循环(例如数7游戏:7的倍数以及含有7的数字都不能读出/输出)。...③for循环结束后的if条件用于判断循环是正常结束还是提前结束,可以考虑用else子句来替代。 ④通过把break语句执行的条件适当修改后放入循环控制条件中,可以取消break语句的使用。

    2800

    手把手教你半个小时用python语言编程出你的第一个程序

    默认情况下,在显示的值之间放置一个空格字符。作为示例,下面print语句的序列: 产生的输出为: 最后一个语句说明了,字符串字面量表达式如何经常在print语句使用,作为标记输出的方便方法。...默认情况下,结束文本是表示行结束的特殊标记字符(表示为“ ”)。我们可以通过包含一个附加参数显式地覆盖这个默认值,从而改变这种行为。这里使用命名参数的特殊语法,或称为“关键字”参数。...包含指定结束文本的关键字参数的print语句的模板如下: 命名参数的关键字是end,它使用“=”符号赋值,类似于变量赋值。注意,在模板中我已经显示其默认值,即行末字符。...print语句中的end参数有一个常见用法,即允许多个print构建单行输出。例如: 注意,第一个print语句的输出如何以空格(" ")而不是行末字符结束,第二个语句的输出紧跟在空格之后。...虽然我们的数字示例特别提示用户输入数字,但在这个例子中,用户键入的只是一个数字字面量,即一个简单的Python表达式。事实上,任何有效的表达式都是可接受的。

    1.8K50

    计算机小白的成长历程——分支与循环(10)

    goto语句 1.理解: goto语句我们在分支与循环(1)中有提到过,它是作为转向语句的一种。...2.使用方法: goto语句的使用格式是: //语句结构 标识符://标识符后跟一个冒号; 正常语句; goto 标识符;//goto语句后跟上标识符,中间用空格隔开,标识符后跟分号代表语句结束; 它具体是如何使用的...我们从这个结果可以看到,相比于一层一层的结束循环,使用goto语句能更快的跳出循环,大大提高了运行效率,这里我们可以做个总结: 1.goto语句作为无条件转移语句,如果随意使用,容易出现bug,在循环中容易进入死循环...CRT_SECURE_NO_WARNINGS 1 #include #include #include int main() { char a[20] = { 0 };//定义字符数组接受输入的字符...那咱们今天的内容到这里就全部结束了,希望这篇内容能帮助大家更好的理解goto语句,接下来随着学习的深入,我会继续给大家分享我在学习过程中的感受,感谢大家的翻阅,咱们下一篇见。

    18320
    领券