程序的语法

本文介绍了如何使用 Python 实现一个简单的四则运算解释器,通过语法图和文法来理解编译器如何解析代码。首先,阐述了编程语言的语法和语法图的作用,并给出一个加减运算的语法图示例。接着,展示了用 Python 编写的四则运算解释器代码,解析整数、加法和减法操作。然后,探讨了文法在编程语言中的重要性,以及如何将文法转换为代码。最后,逐步扩展文法以支持乘除和括号表达式,构建了一个完整的四则运算解释器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

『我不生产代码,我只是代码的搬运工。』当然了,这是一个玩笑。说到代码,我们要学习各种编程语言,学习如何让编译器能懂我们编写的代码。但是,编译器是如何做到能听懂我们的话的呢?按照我们既定的语句一行行的去执行,最终达到我们的目的。这篇文章,我会讲一个很简单的四则运算解释器,通过使用 Python 实现它来一步步了解一个解释器是如何工作的,它们又是怎么得到我们想要的结果的。

语法

计算机语言同样也是一种语言,是一种计算机能够理解的语言,我们想要和计算机对话,就要去学习这种语言。和我们人类的语言一样,计算机语言也是有语法的。以汉语为例,我说『我是中国人』,因为汉语的语法,你听到这句话之后会知道『我』是主语,『是』是谓语,『中国人』是宾语,同时你又很清楚每一个成分的含义,最终理解了整句话的意思。

同样,对于计算机语言也是一样,有着程序的语法,一个解释器知道哪个词是操作数,哪个是操作符,哪个是关键字,它们都有着怎样的含义和功能,通过解释器的解释,计算机明白了某行语句的意义,然后进行运算,得到最后的执行结果。

语法图

语法图就是用来表示一种编程语言语法规则设计的示意图,它很直观的显示出了在一种编程语言中,允许使用的语句和不支持的语句。语法图十分易于阅读:只需跟随箭头指示的路径。一些路径表示选择。另一些路径表示循环。

一个简单的语法图

这里我们举一个语法图的例子:

image

这个语法图就是一个描述了简单的加减运算的语法图,term 在其中的意思就是一个操作数,一开始输入一个操作数,有三条路径可以选择『+』,『-』和退出,如果进入了『+』、『-』路径,则需要再输入一个操作数,之后的路径包括『+』、『-』和退出,如此循环,就能解释一个简单的加减法解释器。

根据上边的语法图,下面的表达式都是合法的:

  • 4
  • 1 + 1
  • 1 + 4 - 3

下面的表达式不合法:

  • -
  • + -
  • 2 +
  • + 3 - 3

语法图可以帮助我们:

  • 用图的方式表示出一种计算机语言的设计规范
  • 可以帮助理解解释器,将图表表示成代码

代码实现(Python)

学习一样东西最简单的就是阅读代码(Read the Fucking Code!),因此我们先来看完整代码然后再来分析一下,完整代码在:https://github.com/luoyhang003/Pascal-Interpreter/blob/master/calc3.py

# Token Types:
# EOF: End-Of-File

INTEGER, PLUS, MINUS, EOF = 'INTEGER', 'PLUS', 'MINUS', 'EOF'

class Token(object):
    def __init__(self, type, value):
        # Token types: INTEGER, PLUS, MINUS, EOF
        self.type = type
        # Token value: 0,1,2,3,4,5,6,7,8,9,+,None
        self.value = value

    def __str__(self):
        """
        The format of the print infomation
        For examle:
        Token(INTEGER, 3)
        Token(PLUS, '+')
        Token(MINUS, '-')
        """
        return 'Token({type},{value})'.format(
                type = self.type,
                value = repr(self.value)
                )

    def __repr__(self):
        return self.__str__()

class Interpreter(object):
    def __init__(self, text):
        # Process the whole input
        # e.g. 3+5
        self.text = text
        self.pos = 0
        self.current_token = None
        self.current_char = self.text[self.pos]

    def error(self):
        raise Exception('Error Parsing Error!')

    def advance(self):
        # Advance the pos and set current_char
        self.pos += 1

        if self.pos > len(self.text)-1:
            self.current_char = None
        else:
            self.current_char = self.text[self.pos]

    def skip_whitespace(self):
        # Skip space
        while self.current_char is not None and self.current_char.isspace():
            self.advance()

    def integer(self):
        # Support mutidigit integer
        result = ''

        while self.current_char is not None and self.current_char.isdigit():
            result += self.current_char
            self.advance()

        return int(result)

    def get_next_token(self):
        """
        Lexical Analyzer:
        Parsing the input into tokens.
        Strategy:
        1. is pos past the end of the text?
        2. if so, return EOF
        3. get a character at pos, and decide its type depends on the single char
        4. if it is a space, advance the pos
        5. if it is a digit, then convert it to integer and return INTEGER token
        6. if it is a '+', then return PLUS token
        7. if it is a '-', then return MINUS token
        """

        while self.current_char is not None
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值