资讯专栏INFORMATION COLUMN

编译原理实战入门:用 JavaScript 写一个简单的四则运算编译器(一)词法分析

wangdai / 2829人阅读

摘要:一般的程序,是无法直接执行的,因为只能识别机器指令。所以要想执行一个程序,首先要将高级语言编写的程序翻译为汇编代码,再将汇编代码翻译为机器指令,这样才能识别并执行。

编译器

编译器是一个程序,作用是将一门语言翻译成另一门语言。

一般的程序,CPU 是无法直接执行的,因为 CPU 只能识别机器指令。所以要想执行一个程序,首先要将高级语言编写的程序翻译为汇编代码,再将汇编代码翻译为机器指令,这样 CPU 才能识别并执行。

示例:

// CPU 无法识别
10 + 5

// 翻译成汇编语言
push 10
push 5
add

// 最后翻译为机器指令 汇编代码和机器指令一一对应
// 机器指令由 1 和 0 组成,以下指令非真实指令,只做演示用
0011101001010101
1101010011100101
0010100111100001

学会编译原理有什么好处?

对编译过程内部原理的掌握将会使你成为更好的高级程序员。

词法分析

程序其实就是保存在文本文件中的一系列字符,词法分析的作用是将这一系列字符按照某种规则分解成一个个字元(token,也称为终结符),忽略空格和注释。

示例:

// 程序代码
10 + 5 + 6

// 词法分析后得到的 token
10
+
5
+
6
终结符

终结符就是语言中用到的基本元素,一般不能再被分解。

四则运算中的终结符包括符号和整数常量(暂不支持一元操作符)。

符号+ - * / ( )

整数常量:12、1000、111...

词法分析代码实现
function lexicalAnalysis(expression) {
    const symbol = ["(", ")", "+", "-", "*", "/"]
    const re = /d/
    const tokens = []
    const chars = expression.trim().split("")
    let token = ""
    chars.forEach(c => {
        if (re.test(c)) {
            token += c
        } else if (c == " " && token) {
            tokens.push(token)
            token = ""
        } else if (symbol.includes(c)) {
            if (token) {
                tokens.push(token)
                token = ""
            } 

            tokens.push(c)
        }
    })

    if (token) {
        tokens.push(token)
    }

    return tokens
}

console.log(lexicalAnalysis("100    +   23   +    34 * 10 / 2")) 
// ["100", "+", "23", "+", "34", "*", "10", "/", "2"]

编译原理实战入门:用 JavaScript 写一个简单的四则运算编译器(一)词法分析

编译原理实战入门:用 JavaScript 写一个简单的四则运算编译器(二)语法分析

编译原理实战入门:用 JavaScript 写一个简单的四则运算编译器(三)模拟执行

编译原理实战入门:用 JavaScript 写一个简单的四则运算编译器(四)结语

完整源码

参考资料:计算机系统要素

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105166.html

相关文章

  • 编译原理实战入门 JavaScript 简单四则运算编译器(四)结语

    摘要:四则运算编译器,虽然说功能很简单,只能编译四则运算表达式。再复杂的编译器再简单的编译器,功能上是差不多的,只是复杂的编译器实现上会更困难。每一章都是理论与实践结合的经典,从计算机硬件知识到软件体系,再到编译原理和操作系统。 四则运算编译器,虽然说功能很简单,只能编译四则运算表达式。但是编译原理前端部分几乎都有涉及,词法分析,语法分析,还有代码生成。 再复杂的编译器、再简单的编译器,功能...

    chemzqm 评论0 收藏0
  • 编译原理实战入门 JavaScript 简单四则运算编译器(三)模拟执行

    摘要:栈在内存中,栈的特点是只能在同一端进行插入和删除的操作,即只有和两种操作。指令的作用是将一个操作数推入栈中。指令的作用是执行两次操作,弹出两个操作数和,然后执行,再将结果到栈中。 现在来模拟一下 CPU 执行机器指令的情况,由于汇编代码和机器指令一一对应,所以我们可以创建一个直接执行汇编代码的模拟器。在创建模拟器前,先来讲解一下相关指令的操作。 栈 在内存中,栈的特点是只能在同一端进行...

    Ku_Andrew 评论0 收藏0
  • 编译原理实战入门 JavaScript 简单四则运算编译器(二)语法分析

    摘要:语法分析对输入的文本按照语法规则进行分析并确定其语法结构的一种过程,称为语法分析。递归下降分析法递归下降分析法,也称为自顶向下分析法。表达式代码生成我们通常用的四则运算表达式是中缀表达式,但是对于计算机来说中缀表达式不便于计算。 四则运算的语法规则(语法规则是分层的) x* 表示 x 出现零次或多次 x | y 表示 x 或 y 将出现 ( ) 圆括号,用于语言构词的分组 以下规则...

    hankkin 评论0 收藏0
  • 重学前端学习笔记(二十八)--通过四则运算解释器快速理解编译原理

    摘要:实现状态机可能产生四种输入元素,其中只有两种,状态机的第一个状态就是根据第一个输入字符来判断进入了哪种状态用函数表示状态,用表示状态的迁移关系,用值表示下一个状态。运行状态机输出结果四语法分析语法分析根据每一个产生式来写一个函数。 笔记说明 重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点...

    Towers 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<