如何更改规则的解析顺序?

时间:2016-08-19 05:18:38

标签: python parsing yacc ply

I'm developing a programming language,我在处理条件陈述方面遇到了麻烦。这是我的语言代码:

x = 4 ->
? 2 > 5 <?
    x = 7 -> 
?> ->
[o] <- x ->

以下是定义条件语句的语法的特定部分:

post_condition_evaluation_block : post_condition_evaluation_block_opening_operator compound_statement post_condition_evaluation_block_closing_operator
condition_statement : condition_specification_operator expression post_condition_evaluation_block
                    | condition_specification_operator expression post_condition_evaluation_block condition_extension

语法没有任何问题,代码正常运行。问题是表达式2 > 5在以下语句x = 7之后被评估,因此打印的是7而不是4(这是错误的,因为表达式的计算结果为false )。我正在处理这个计算条件块的问题:

condition_blocks = {0: True}
current_condition_block = 0

然后谈到条件声明:

def p_condition_statement(p):
    """condition_statement : condition_specification_operator expression post_condition_evaluation_block
                           | condition_specification_operator expression post_condition_evaluation_block condition_extension"""
    global current_condition_block
    current_condition_block += 1
    condition_blocks[current_condition_block] = p[2]
    print(condition_blocks)

它将表达式的False(p 2)的值添加到字典中的相应块索引。问题在于,当我完成任务时:

def p_assignment(p):
    """assignment : identifier assignment_operator expression"""
    if len(p) == 4 and condition_blocks[current_condition_block]:
        if p[2] == '=':
            identifiers[p[1]] = parse_object(p[3])
        elif p[2] == "+=":
            identifiers[p[1]] += parse_object(p[3])
        elif p[2] == "-=":
            identifiers[p[1]] -= parse_object(p[3])
        elif p[2] == "*=":
            identifiers[p[1]] *= parse_object(p[3])
        elif p[2] == "/=":
            identifiers[p[1]] /= parse_object(p[3])
        p[0] = (p[1], p[2], p[3])

获得评估的块是默认的“out-of-block-scope”。分配规则在表达式之前被解析/处理,这在我的脑海中没有任何意义,因为整个代码应该从头到尾进行处理。

我显然不是解析/ YACC的专家,这是我的第一次尝试,我发现绝对没有提示做什么in the docs。我不知道如何停止解析器,跳过解析器,更改解析顺序......也许问题在于我的语法,但我看不出如何更改解析顺序。

1 个答案:

答案 0 :(得分:1)

当生产减少 - 也就是说,执行其语义动作 - 所有引用的非终端都已减少。换句话说,孩子总是在父母面前减少,这就是为什么yacc被称为自下而上的解析器。

实现更大灵活性的唯一实用方法是在解析期间构建AST,然后通过在AST上进行树形游戏来评估(或其他)完整表达式。然后,您可以按照任何合适的顺序自由地走完整棵树。