吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1282|回复: 1
收起左侧

[Python 原创] ply编译语言的应用研究

[复制链接]
话痨司机啊 发表于 2023-4-2 23:01
本帖最后由 话痨司机啊 于 2023-4-2 23:07 编辑

Ply中lex与yacc搭配使用
一、lex是用来标记语言中的特殊标记,在tokens 中定义字段
    优先级:t_**的方法>正则长度(越长则优先级越高)
二、yacc 使用BNF语言解析标记字段,堆栈方式解析(先进后出,后进先出原则)
    优先级:precedence 关键字定义优先级,left中第一行level是1级,第二行level2,以此类推,等级level越高则优先级越高,当left和right堆栈中冲突时,则left减少,right转移。nonassoc 关键字一般用来定义非关联字符如“><“”等
三、关于语法常见错误
1.递归错误:一般为BNF语法定义无终端引起
2.此关键词生成错误
[Python] 纯文本查看 复制代码
def p_production(p):
    'production : some production ...'
    raise SyntaxError

3.令牌错误(语法标记问题,令牌问题)


以下为示例:
[Python] 纯文本查看 复制代码
from ply import yacc, lex


class Parse:
    def __init__(self, name, debug: bool = False):
        self.name = name
        self.debug = debug
        self.lexer = lex.lex(module=self)
        self.parser = yacc.yacc(module=self)

    def print_input(self):
        self.lexer.input(self.name)
        for tok in self.lexer:
            print(tok)

    def exec(self):
        return self.parser.parse(self.name, debug=self.debug)


class BaseParse(Parse):
    def __init__(self, name):
        super().__init__(name)

    # List of token names.   This is always required
    tokens = (
        'NUMBER',
        'PLUS',
        'MINUS',
        'TIMES',
        'DIVIDE',
        'LPAREN',
        'RPAREN',
    )

    # Regular expression rules for simple tokens
    t_PLUS = r'\+'
    t_MINUS = r'-'
    t_TIMES = r'\*'
    t_DIVIDE = r'/'
    t_LPAREN = r'\('
    t_RPAREN = r'\)'

    # A regular expression rule with some action code
    def t_NUMBER(self, t):
        r'\d+'
        t.value = int(t.value)
        return t

    # Define a rule so we can track line numbers
    def t_newline(self, t):
        r'\n+'
        t.lexer.lineno += len(t.value)

    # A string containing ignored characters (spaces and tabs)
    t_ignore = '\t'

    # Error handling rule
    def t_error(self, t):
        print("Illegal character '%s'" % t.value[0])
        t.lexer.skip(1)

    precedence = (
        ('left', 'PLUS', 'MINUS'),
        ('left', 'TIMES', 'DIVIDE'),
        ('right', 'UMINUS'),
    )

    def p_expression_plus(self, p):
        "expression : expression PLUS expression"
        p[0] = p[1] + p[3]

    def p_expression_minus(self, p):
        'expression : expression MINUS expression'
        p[0] = p[1] - p[3]

    def p_term_times(self, p):
        'expression : expression TIMES expression'
        p[0] = p[1] * p[3]

    def p_term_div(self, p):
        'expression : expression DIVIDE expression'
        p[0] = p[1] / p[3]

    def p_factor_num(self, p):
        'expression : NUMBER'
        p[0] = p[1]

    def p_expr_uminus(self, p):
        'expression : MINUS expression %prec UMINUS'
        p[0] = -p[2]

    def p_factor_expr(self, p):
        'expression : LPAREN expression RPAREN'
        p[0] = p[2]

    def p_error(self, p):
        print("Syntax error in input!")


class Filter:
    def __init__(self):
        self.filter = BaseParse(data)
        self.print_lex_signle()
        self.exec()

    def exec(self):
        reslut = self.filter.exec()
        print(reslut)

    def print_lex_signle(self):
        self.filter.print_input()


if __name__ == "__main__":
    data = "-5+(2*-3)"  # 必须有data字段
    Filter()


运行结果:
Snipaste_2023-04-02_22-48-54.png

免费评分

参与人数 2吾爱币 +8 热心值 +2 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
whizzer + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

whizzer 发表于 2023-4-6 07:50
谢谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 23:46

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表