scau编译原理实验(C.1,C.2,C.3,C.5

简介

csdn上有c语言实现的,我就不搞了,这里整理了份python实现的

注:C.3以及C.5采用了另外一种方法实现词法分析

GitHub:https://github.com/William3147076912/Compilation-principle-scau

C.1

p_input = 0


class Word:

    def __init__(self, typenum=10, word=""):
        """
        初始化Word类,用于存储词法分析结果。

        :param typenum: 单词的类型编号,默认为10(标识符)
        :param word: 单词字符串,默认为空字符串
        """
        self.typenum = typenum
        self.word = word


def scanner(input_str):
    """
    词法扫描器,从输入字符串中提取单词并返回其类型和值。

    :param input_str: 输入字符串
    :return: Word对象,包含单词的类型和值
    """
    rwtab = ["begin", "if", "then", "while", "do", "end"]  # 关键字表
    global p_input  # 当前读取位置
    token = ""  # 当前单词缓冲区

    def getch():
        """
        从输入字符串中读取一个字符。

        :return: 当前字符,如果到达字符串末尾则返回'\0'
        """
        global p_input
        if p_input < len(input_str):
            ch = input_str[p_input]
            p_input += 1
            return ch
        return '\0'

    def getbc():
        """
        跳过空白字符(空格、换行、制表符)。

        :return: 下一个非空白字符
        """
        ch = getch()
        while ch in (' ', '\n', '\t'):
            ch = getch()
        return ch

    def concat(ch):
        """
        将字符追加到当前单词缓冲区。

        :param ch: 要追加的字符
        """
        nonlocal token
        token += ch

    def letter(ch):
        """
        判断字符是否为字母。

        :param ch: 要判断的字符
        :return: 如果是字母返回True,否则返回False
        """
        return 'a' <= ch <= 'z' or 'A' <= ch <= 'Z'

    def digit(ch):
        """
        判断字符是否为数字。

        :param ch: 要判断的字符
        :return: 如果是数字返回True,否则返回False
        """
        return '0' <= ch <= '9'

    def reserve():
        """
        检查当前单词是否为关键字。

        :return: 如果是关键字返回其类型编号,否则返回10(标识符)
        """
        for i, kw in enumerate(rwtab):
            if token == kw:
                return i + 1
        return 10

    def retract():
        """
        回退一个字符。
        """
        global p_input
        p_input -= 1

    ch = getbc()  # 获取第一个非空白字符
    if letter(ch):
        # 处理标识符
        while letter(ch) or digit(ch):
            concat(ch)
            ch = getch()
        retract()
        return Word(reserve(), token)
    elif digit(ch):
        # 处理数字
        while digit(ch):
            concat(ch)
            ch = getch()
        retract()
        return Word(11, token)
    else:
        # 处理特殊字符
        if ch == '=':
            getch()
            if ch == '=':
                return Word(39, "==")
            retract()
            return Word(25, '=')
        elif ch == '+':
            return Word(13, '+')
        elif ch == '-':
            return Word(14, '-')
        elif ch == '*':
            return Word(15, '*')
        elif ch == '/':
            return Word(16, '/')
        elif ch == '(':
            return Word(27, '(')
        elif ch == ')':
            return Word(28, ')')
        elif ch == '[':
            return Word(29, '[')
        elif ch == ']':
            return Word(30, ']')
        elif ch == '{':
            return Word(31, '{')
        elif ch == '}':
            return Word(32, '}')
        elif ch == ',':
            return Word(33, ',')
        elif ch == ':':
            next_ch = getch()
            if next_ch == '=':
                return Word(18, ':=')
            retract()
            return Word(17, ':')
        elif ch == ';':
            return Word(26, ';')
        elif ch == '>':
            next_ch = getch()
            if next_ch == '=':
                return Word(24, '>=')
            retract()
            return Word(23, '>')
        elif ch == '<':
            next_ch = getch()
            if next_ch == '=':
                return Word(22, '<=')
            retract()
            return Word(20, '<')
        elif ch == '!':
            next_ch = getch()
            if next_ch == '=':
                return Word(40, '!=')
            retract()
            return Word(-1, 'ERROR')
        elif ch == '\0':
            return Word(1000, 'OVER')
        elif ch in ('\n', '\t'):
            return Word(-1, 'ERROR')  # 这里可以调整逻辑,根据需求处理换行和制表符
        else:
            return Word(-1, f'ERROR: Unexpected character {ch}')


def main():
    """
    主函数,处理用户输入并调用词法扫描器。
    """
    while True:
        print("Enter Your words (end with #):")
        input_str = input().strip('#')  # 读取用户输入并去掉末尾的#
        over = 1
        global p_input
        p_input = 0
        while over < 1000 and over != -1:
            oneword = scanner(input_str)
            if oneword.word in ('\n', '\t'):
                continue
            if oneword.typenum < 1000:
                if oneword.typenum == 10:
                    print(f"({oneword.typenum}, '{oneword.word}')", end=' ')
                else:
                    print(f"({oneword.typenum}, {oneword.word})", end=' ')
                    # print(p_input)
                    # exit(0)
            over = oneword.typenum
        print("\npress #
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值