编译原理实战:S属性与L属性在表达式解析中的对比与应用

1. 从表达式解析看S属性与L属性的本质区别

我第一次接触S属性和L属性是在实现一个简单的数学表达式计算器时。当时需要处理类似"3*(5+2)-4"这样的表达式,但发现不同解析方式对计算顺序和结果有巨大影响。这让我意识到属性计算顺序的重要性。

**S属性(综合属性)*就像搭积木,必须从最底层的积木开始,一层层向上构建。在表达式"3(5+2)"中,必须先计算"5+2=7",再用结果计算"3*7"。这种自底向上的计算方式天然适合栈结构,也是大多数计算器的工作方式。

# S属性风格的计算器实现示例
def eval_expression(tokens):
    stack = []
    for token in tokens:
        if token.isdigit():
            stack.append(int(token))  # 数字直接入栈
        else:
            b = stack.pop()  # 先弹出右操作数
            a = stack.pop()  # 再弹出左操作数
            if token == '+': stack.append(a + b)
            elif token == '*': stack.append(a * b)
    return stack[0]

**L属性(继承属性)**则像传家宝,属性值从父节点传递给子节点。比如在类型声明"int a,b,c"中,类型信息"int"需要沿着语法树向下传递到每个变量。这种自上而下的特性天然适合递归下降解析。

# L属性风格的类型声明处理示例
def parse_declaration(decl_type):
    variables = []
    while has_more_tokens():
        var = parse_identifier()
        var.type = decl_type  # 类型信
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值