如何知道层数减少的规则编号?

时间:2019-03-11 12:03:14

标签: compiler-construction yacc ply

假设我的语法中有以下规则。我想知道是从哪个规则减少发生的。

iteration_statement : WHILE push_scope LPAREN expression  RPAREN  compound_statement pop_scope 
                           | DO push_scope compound_statement WHILE LPAREN expression  RPAREN  SEMICOLON pop_scope 
                           | FOR LPAREN push_scope for_init_statement expression SEMICOLON expression  RPAREN  compound_statement pop_scope 
                           | FOR LPAREN push_scope for_init_statement SEMICOLON expression  RPAREN  compound_statement pop_scope 
                           | FOR LPAREN push_scope for_init_statement expression SEMICOLON  RPAREN  compound_statement pop_scope 
                           | FOR LPAREN push_scope for_init_statement SEMICOLON  RPAREN  compound_statement pop_scope

我想做这样的事情

if p.ruleno==1:
   #action for while
elif p.ruleno==2:
  # action for do while
elif p.ruleno==3:
    # action for for in rule 3
elif p.ruleno==4:
   # action for for in rule 4
elif p.ruleno==5:
    # action for for in rule 5
elif p.ruleno==6:
   # action for for in rule 6

2 个答案:

答案 0 :(得分:1)

那不是Ply的工作方式。将每个产品置于自己的功能中:

def p_iter_1(p):
    '''iteration_statement : WHILE push_scope LPAREN expression  RPAREN  statement pop_scope'''
     # Do action 1

def p_iter_2(p):
    '''iteration_statement : DO push_scope statement WHILE LPAREN expression  RPAREN  SEMICOLON pop_scope''''
    # Do action 2

def p_iter_3(p):
    '''iteration_statement : FOR LPAREN push_scope for_init_statement expression SEMICOLON expression  RPAREN  compound_statement pop_scope'''
    # Do action 3

# Etc.

解析器将归约函数与每个产品相关联。如果您在简化功能的文档字符串中放置多个生产,则该功能将与每个生产相关联。如果操作相同,也可以。 (而且它们甚至不需要还原为相同的非终结符。)但是,如果操作不同,则最简单的解决方案是使用不同的功能。

答案 1 :(得分:1)

您可以将不同类型的循环放入不同的函数中:

def p_while(p):
    'iteration_statement : WHILE push_scope LPAREN expression  RPAREN  compound_statement pop_scope'
    #action for while

def p_do_while(p):
    'iteration_statement : DO push_scope compound_statement WHILE LPAREN expression  RPAREN  SEMICOLON pop_scope'
    #action for do while

def p_for(p):
    'iteration_statement : FOR LPAREN push_scope for_init_statement expression_opt SEMICOLON expression_opt  RPAREN  compound_statement pop_scope'
    # action for for

注意:我已经将for循环的规则简化为仅具有单个大小写(带有可选表达式),因此您可以在单个方法中处理for循环,而不必以某种方式检查哪个四个选择中的一个都被匹配了。