首页 > 其他分享 >从0开始自制解释器——实现多个整数的加减法

从0开始自制解释器——实现多个整数的加减法

时间:2023-03-14 17:46:00浏览次数:60  
标签:oper 解释器 bRet get 自制 语法 token pRet 加减法

在上一篇我们实现了一个可以计算两个多位整数加减法的计算器。本章我们继续来给这个计算器添加功能,这次要给它添加可以连续计算多个整数相加减的功能。例如我们可以计算 1 + 2 + 3 这样的表达式。

语法图

在正式写代码之前让我们先来学习一下一些基本的理论知识。这次要介绍的理论是语法图

什么是语法图呢?语法图是编程语言语法语法规则的图形表示。它体现了词法分析的运行规则。语法图直观的展示了在编程语言中哪些语句是符合语法的,哪些是不符合语法规范的。

语法图的阅读非常容易,它类似于程序的流程图,只要顺着箭头指向的路径来读即可。与程序流程图类似,语法图中有些路径表示选择,有些表示循环。我们试着来读一下下面的语法图
在这里插入图片描述

这张语法图表示的含义是,一个术语(term) 可选的跟上一个加号或者减号,而后面又需要跟上另一个术语。接着又可以有选择的跟上另一个加号或者减号。但是加号或者减号后面必须跟上另一个术语。

这里又提到另一个单词,term 它的中文意思是术语。似乎很难用其他文字来解释何为术语。你只需要知道在这里它代表的是一个整数,它并不影响我们阅读这个语法图

代码展示

在上一篇中我们提到,将Token流识别为对应结构的过程被称之为词法分析,我们代码中的词法分析的实现主要在函数 expr 中。在这个函数中我们主要实现了词法分析以及最后的解释执行。我们按照语法图修改一下词法分析的代码

我们先给出下面的伪代码

获取第一个整数作为计算结果保存
while(解析到最后一个字符)
{
    获取操作符(+/-)
    switch(操作符)
    {
        case +:
            获取下一个整数,如果不是整数则退出并报错
            与结果相加
            break;
        case -:
            获取下一个整数,如果不是整数则退出并报错
            与结果相减
            break;
    }
}

最终打印计算结果或者打印语法错误

基于这个思路我们给出具体的实现代码

int expr()
{
    bool bRet = false;
    int result = get_term(&bRet);
    int bEOF = false;
    do
    {
        ETokenType oper = get_oper(&bRet);
        switch (oper)
        {
            case PLUS:
            {
                int num = get_term(&bRet);
                if(bRet)
                    result += num;
            }
            break;
        case MINUS:
            {
                int num = get_term(&bRet);
                if(bRet)
                    result -= num;
            }
            break;
        case END_OF_FILE:
            printf("%d\n", result);
            bEOF = true;
            break;
        default:
            bRet = false;
            break;
        }
    } while (bRet && !bEOF);
    if (!bRet)
    {
        printf("Syntax Error!\n");
    }
}

这里为了便于理解,我将获取整数和操作符的模块又进行了一次封装,提供了两个函数分别是 get_term()get_oper()。它们的代码如下

int get_term(bool *pRet)
{
    Token token = { 0 };
    dyncstring_init(&token.value, DEFAULT_BUFFER_SIZE);
    int value = 0;
    if (get_next_token(&token) && token.type == CINT)
    {
        value = atoi(token.value.pszBuf);
        if (pRet)
            *pRet = true;
    }
    else
    {
        if (pRet)
            *pRet = false;
    }
    dyncstring_free(&token.value);

    return value;
}
ETokenType get_oper(bool* pRet)
{
    Token token = { 0 };
    dyncstring_init(&token.value, DEFAULT_BUFFER_SIZE);
    int oper = 0;
    if (get_next_token(&token) && (token.type == PLUS || token.type == MINUS))
    {
        oper = token.type;
        if (pRet)
            *pRet = true;
    }
    else if (token.type == END_OF_FILE)
    {
        oper = END_OF_FILE;
        if (pRet)
            *pRet = true;
    }
    else
    {
        oper = -1;
        if (pRet)
            *pRet = false;
    }

    dyncstring_free(&token.value);
    return oper;
}

到此为止,就实现了多个整数的算术运算。整个实现过程的代码我都放到该位置。有兴趣的小伙伴可以自己对照着代码跟着我一起来实现属于自己的解释器。

标签:oper,解释器,bRet,get,自制,语法,token,pRet,加减法
From: https://www.cnblogs.com/lanuage/p/17215724.html

相关文章

  • 向量的加减法与内外积
     假设有两个向量a=(x,y,z)、b=(i,j,k),它们之间的夹角为θ1、加法数学运算:a+b=(x+i,y+j,z+k)例如a=(1,2,4)b=(3,5,6),那么a+b=(1+3,2+5,4+6)=(4,7,10)向量加法符......
  • 23-解释器模式
    23-解释器模式概念解释器模式(interpreter),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。如果一种特定类型的问题发生......
  • 从0开始自制解释器——实现多位整数的加减法计算器
    上一篇我们实现了一个简单的加法计算器,并且了解了基本的词法分析、词法分析器的概念。本篇我们将要对之前实现的加法计算器进行扩展,我们为它添加以下几个功能计算减法能......
  • 判断jupyter中python解释器的版本
    查看解释器中的python版本importsysprint(sys.executable)print(sys.path)#更具体查看jupyternotebook中shell的版本信息!whichpython类似命令whereispyth......
  • 从0开始自制解释器——综述
    作为一个程序员,自制自己的编译器一直是一个梦想。之前也曾为了这个梦想学习过类似龙书、虎书这种大部头的书,但是光看理论总有一些云里雾里的感觉。看完只觉得脑袋昏昏沉沉......
  • 正点原子IMX6ULL开发板-烧写自制系统-启动kernel后显示“No working init found”问题
    环境VMware17.0.0Ubuntu16NXP提供的U-boot与Linux版本:u-boot:uboot-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2linux:linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2开发板:......
  • 解释器模式
    解释器模式是一种行为型设计模式,它可以用来定义和解释一种语言的文法,并根据文法对句子进行解释。解释器模式通常用于编译器,表达式计算,正则表达式,机器人等领域。它的基本思......
  • #创作者激励#【FFH】自制ArkUI组件-文件管理器(二)悬浮小球!
    【本文正在参加2023年第一期优质创作者激励计划】前言交互设计UI整体设计UI自适应布局悬浮窗改造效果图GIFEND前言经过重重的改造封装,这一版的FilerBall组件基本......
  • 【FFH】自制一款ArkUI组件-应用文件管理器(一)
    前言介绍使用示例1.实现思路1.1接口函数1.2代码思路效果图GIF前言在涉及应用内部存储的开发时,常常翻阅手机自带的文件管理检查。正好在学习文件管理的接口,想着......
  • 0x07_自制操作系统My-OS实现输出字符到屏幕
    接上一课class04,这是他的运行结果 收到了键盘的中断,现在想的当然是怎么把输入的文字显示到屏幕上,做成一个最简单的IO 这是class04的目录结构,现在我们把他换成clas......