Syntax 如何解决这种转变/减少冲突?

Syntax 如何解决这种转变/减少冲突?,syntax,grammar,conflict,ply,Syntax,Grammar,Conflict,Ply,我的代码中有以下语法 Rule 0 S' -> program Rule 1 write -> WRITE LPAREN expression_list RPAREN SEMICOLON Rule 2 read -> READ LPAREN expression_list RPAREN SEMICOLON Rule 3 program -> function Rule 4 function -> identifier iden

我的代码中有以下语法

Rule 0     S' -> program
Rule 1     write -> WRITE LPAREN expression_list RPAREN SEMICOLON
Rule 2     read -> READ LPAREN expression_list RPAREN SEMICOLON
Rule 3     program -> function
Rule 4     function -> identifier identifier formal_parameters block
Rule 5     function -> VOID identifier formal_parameters block
Rule 6     formal_parameters -> LPAREN formal_parameter formal_parameters_list RPAREN
Rule 7     formal_parameters -> LPAREN empty RPAREN
Rule 8     formal_parameters_list -> SEMICOLON formal_parameter formal_parameters_list
Rule 9     formal_parameters_list -> empty
Rule 10    empty -> <empty>
Rule 11    formal_parameter -> expression_parameter
Rule 12    formal_parameter -> function_parameter
Rule 13    function_parameter -> VOID identifier formal_parameters
Rule 14    function_parameter -> INTEGER identifier formal_parameters
Rule 15    function_parameter -> identifier identifier formal_parameters
Rule 16    expression_parameter -> identifier_list COLON INTEGER
Rule 17    expression_parameter -> VAR identifier_list COLON INTEGER
Rule 18    identifier_list -> identifier
Rule 19    identifier_list -> identifier_list COMMA identifier
Rule 20    block -> body
Rule 21    block -> labels body
Rule 22    block -> labels variables body
Rule 23    block -> labels variables functions body
Rule 24    block -> labels functions body
Rule 25    block -> variables body
Rule 26    block -> variables functions body
Rule 27    block -> functions body
Rule 28    functions -> FUNCTIONS function_list
Rule 29    function_list -> function
Rule 30    function_list -> function function_list
Rule 31    variables -> VARS identifier_list COLON type SEMICOLON
Rule 32    type -> INTEGER
Rule 33    labels -> LABELS identifier_list SEMICOLON
Rule 34    body -> LBRACES stamement_list RBRACES
Rule 35    stamement_list -> statement stamement_list
Rule 36    stamement_list -> empty
Rule 37    statement -> unlabeled_statement
Rule 38    statement -> compound
Rule 39    unlabeled_statement -> assignment
Rule 40    unlabeled_statement -> function_call_statement
Rule 41    unlabeled_statement -> goto
Rule 42    unlabeled_statement -> return
Rule 43    unlabeled_statement -> conditional
Rule 44    unlabeled_statement -> repetitive
Rule 45    unlabeled_statement -> empty_statement
Rule 46    unlabeled_statement -> write
Rule 47    unlabeled_statement -> read
Rule 48    goto -> GOTO identifier SEMICOLON
Rule 49    return -> RETURN return_optional
Rule 50    return_optional -> expression
Rule 51    return_optional -> empty
Rule 52    function_call_statement -> function_call SEMICOLON
Rule 53    function_call -> IDENTIFIER LPAREN expression_list_and_empty RPAREN
Rule 54    expression_list_and_empty -> empty
Rule 55    expression_list_and_empty -> expression_list
Rule 56    expression_list -> expression
Rule 57    expression_list -> expression_list COMMA expression
Rule 58    repetitive -> WHILE LPAREN expression RPAREN compound
Rule 59    compound -> LBRACES compound_list RBRACES
Rule 60    compound_list -> unlabeled_statement
Rule 61    compound_list -> compound_list unlabeled_statement
Rule 62    empty_statement -> SEMICOLON
Rule 63    assignment -> identifier EQUALS expression SEMICOLON
Rule 64    variable -> identifier
Rule 65    variable -> identifier LBRACKETS expression_list RBRACKETS
Rule 66    expression -> simple_expression expression_optional
Rule 67    expression_optional -> relational_operator simple_expression
Rule 68    expression_optional -> empty
Rule 69    relational_operator -> COMPAREEQUAL
Rule 70    relational_operator -> NOTEQQUAL
Rule 71    relational_operator -> LESS
Rule 72    relational_operator -> LESSEQUAL
Rule 73    relational_operator -> GREATQUAL
Rule 74    relational_operator -> GREAT
Rule 75    conditional -> IF LPAREN expression RPAREN compound
Rule 76    conditional -> IF LPAREN expression RPAREN compound ELSE compound
Rule 77    simple_expression -> term simple_expression_list
Rule 78    simple_expression_list -> additive_operator term simple_expression_list
Rule 79    simple_expression_list -> empty
Rule 80    additive_operator -> PLUS
Rule 81    additive_operator -> MINUS
Rule 82    term -> factor multiplicative_operator_list
Rule 83    multiplicative_operator -> TIMES
Rule 84    multiplicative_operator -> DIVIDE
Rule 85    multiplicative_operator_list -> multiplicative_operator factor multiplicative_operator_list
Rule 86    multiplicative_operator_list -> empty
Rule 87    factor -> NUMBER
Rule 88    factor -> variable
Rule 89    factor -> LPAREN expression RPAREN
Rule 90    factor -> function_call
Rule 91    identifier -> IDENTIFIER
我试图解决这个问题,但最终我制造了更多的冲突,我以前遇到过其他冲突,但我总是在冲突发生后立即进行保存,但我最终试图修复这个问题,但现在我无法轻松识别它

有人有主意吗

补语语法

### Write Function ###
def p_write(p):
    '''write : WRITE LPAREN expression_list RPAREN SEMICOLON'''
    p[0] = ('write', p[3])

### Read Function ###
def p_read(p):
    '''read : READ LPAREN expression_list RPAREN SEMICOLON'''
    p[0] = ('read', p[3])


def p_program(p):
    '''program : function'''
    p[0] = p[1]


def p_function(p):
    '''function : identifier identifier formal_parameters block
                | VOID identifier formal_parameters block'''
    p[0] = [p[1], p[2], p[3], p[4]]


def p_formal_parameters(p):
    '''formal_parameters : LPAREN formal_parameter formal_parameters_list RPAREN
                         | LPAREN empty RPAREN'''
    p[0] = p[2]

def p_formal_parameters_list(p):
    '''formal_parameters_list : SEMICOLON formal_parameter formal_parameters_list
                              | empty'''
    if len(p) == 4:
        p[0] = p[3]
        p[0].append(p[2])

    elif len(p) == 2:
        p[0] = [p[1]]

def p_empty(p):
    'empty :'
    pass

def p_formal_parameter(p):
    '''formal_parameter : expression_parameter
                        | function_parameter'''
    p[0] = p[1]

def p_function_parameter(p):
    '''function_parameter : VOID identifier formal_parameters
                          | INTEGER identifier formal_parameters
                          | identifier identifier formal_parameters'''

    p[0] = (p[1], p[2], p[3])

# Mudei um detalhe aqui
def p_expression_parameter(p):
    '''expression_parameter : identifier_list COLON INTEGER
                            | VAR identifier_list COLON INTEGER'''

    if len(p) == 4:
        p[0] = (p[1], p[3])

    elif len(p) == 5:
        p[0] = (p[2], p[4])

def p_identifier_list(p):
    '''identifier_list : identifier
                       | identifier_list COMMA identifier'''
    if len(p) == 4:
        p[0] = p[1]
        p[0].append(p[3])
    elif len(p) == 2:
        p[0] = [p[1]]

def p_block(p):
    '''block : body
             | labels body
             | labels variables body
             | labels variables functions body
             | labels functions body
             | variables body
             | variables functions body
             | functions body'''

    # body
    if len(p) == 2:
        p[0] = p[1]

    # labels body
    # variables body
    # functions body
    elif len(p) == 3:
        p[0] = (p[1], p[2])

    # labels variable body
    # labels functions body
    # variables functions body
    elif len(p) == 4:
        p[0] = (p[1], p[2], p[3])

    #labels variables functions body
    elif len(p) == 5:
        p[0] = (p[1], p[2], p[3], p[4])

def p_functions(p):
    '''functions : FUNCTIONS function_list'''

    p[0] = p[2]

def p_functions_list(p):
    '''function_list  : function 
                      | function function_list'''

    if len(p) == 3:
        p[0] = p[2]
        p[0].append(p[1])

    elif len(p) == 2:
        p[0] = [p[1]]

def p_variables(p):
    '''variables : VARS identifier_list COLON type SEMICOLON'''

    p[0] = (p[2], p[4])

def p_type(p):
    '''type : INTEGER'''
    p[0] = p[1]

def p_labels(p):
    '''labels : LABELS identifier_list SEMICOLON'''
    p[0] = ('labels', p[2])

def p_body(p):
    '''body : LBRACES stamement_list RBRACES '''
    p[0] = p[2]

def p_stamement_list(p):
    '''stamement_list : statement stamement_list
                      | empty'''

    if len(p) == 3:
        p[0] = p[2]
        p[0].append(p[1])

    elif len(p) == 2:
        p[0] = [None]

def p_statement(p):
    '''statement : unlabeled_statement 
                 | compound'''
    p[0] = p[1]

def p_unlabeled_statement(p):
    '''unlabeled_statement : assignment
                           | function_call_statement
                           | goto
                           | return
                           | conditional
                           | repetitive
                           | empty_statement
                           | write
                           | read'''
    p[0] = p[1]


def p_goto(p):
    '''goto : GOTO identifier SEMICOLON'''
    p[0] = ('goto', p[2])

def p_return(p):
    '''return : RETURN return_optional'''
    p[0] = (p[2])

def p_return_optional(p):
    '''return_optional : expression
                       | empty'''
    p[0] = (p[1])

def p_function_call_statement(p):
    '''function_call_statement : function_call SEMICOLON'''
    p[0] = p[1]

def p_function_call(p):
    '''function_call :  IDENTIFIER LPAREN expression_list_and_empty RPAREN'''
    p[0] = (p[1], [p[3]])

def p_expression_list_and_empty(p):
    '''expression_list_and_empty : empty 
                                 | expression_list'''
    p[0] = p[1]

def p_expression_list(p):
    '''expression_list : expression 
                       | expression_list COMMA expression'''

    if len(p) == 4:
        p[0] = p[1]
        p[0].append(p[3])

    elif len(p) == 2:
        p[0] = [p[1]]

def p_repetitive(p):
    '''repetitive : WHILE LPAREN expression RPAREN compound'''
    p[0] = (p[3], p[5])

def p_compound(p):
    '''compound : LBRACES compound_list RBRACES'''
    p[0] = ('{', p[2], '}')

def p_compound_list(p):
    '''compound_list : unlabeled_statement
                     | compound_list unlabeled_statement'''

    if len(p) == 3:
        p[0] = p[1]
        p[0].append(p[2])

    elif len(p) == 2:
        p[0] = [p[1]]


def p_empty_statement(p):
    '''empty_statement : SEMICOLON'''
    p[0] = None


def p_assignment(p):
    '''assignment : identifier EQUALS expression SEMICOLON'''
    p[0] = p[1]


def p_variable(p):
    '''variable : identifier 
                | identifier LBRACKETS expression_list RBRACKETS'''
    p[0] = p[1]

def p_expression(p):
    '''expression : simple_expression expression_optional'''
    p[0] = (p[1], p[2])

def p_expression_optional(p):
    '''expression_optional : relational_operator simple_expression
                           | empty'''

    if len(p) == 3:
        p[0] = (p[1], p[2])

    if len(p) == 2:
        p[0] = None

def p_relational_operator(p):
    '''relational_operator : COMPAREEQUAL
                           | NOTEQQUAL
                           | LESS 
                           | LESSEQUAL
                           | GREATQUAL
                           | GREAT'''

    p[0] = p[1]


def p_conditional(p):
    '''conditional : IF LPAREN expression RPAREN compound 
                   | IF LPAREN expression RPAREN compound ELSE compound'''

    if len(p) == 6:
        p[0] = ('IF', p[3], p[5])

    if len(p) == 8:
        p[0] = ('IF', p[3], p[5], 'ELSE', p[7])


def p_simple_expression(p):
    '''simple_expression : term simple_expression_list'''
    p[0] = (p[1], p[2])

def p_simple_expression_list(p):
    '''simple_expression_list : additive_operator term simple_expression_list
                              | empty '''

    if len(p) == 4:
        p[0] = p[3]
        p[0].append( (p[1], p[2]) )

    elif len(p) == 2:
        p[0] = [None]

def p_additive_operator(p):
    '''additive_operator : PLUS 
                         | MINUS'''
    p[0] = p[1]

def p_term(p):
    '''term : factor multiplicative_operator_list'''
    p[0] = p[1]

def p_multiplicative_operator(p):
    '''multiplicative_operator : TIMES
                               | DIVIDE'''
    p[0] = p[1]

def p_multiplicative_operator_list(p):
    '''multiplicative_operator_list : multiplicative_operator factor multiplicative_operator_list
                                    | empty'''

    if len(p) == 4:
        p[0] = p[3]
        p[0].append( (p[1], p[2]) )

    elif len(p) == 2:
        p[0] = [None]

def p_factor(p):
    '''factor : NUMBER
              | variable
              | LPAREN expression RPAREN
              | function_call'''

    p[0] = p[1]

def p_identifier(p):
    '''identifier : IDENTIFIER'''
    p[0] = p[1]

def p_error(p):
    print("Error", p)

您忘记用分号终止return语句。由于return语句采用可选表达式,并且后面可能跟有表达式语句,因此表达式后面的
return
标记是不明确的。因此产生了冲突。

如果你不介意的话,我们可以看看语法吗?空的
有什么意义?另外,我建议您将
形式参数列表
更改为与其他列表相同的左递归形式。但我认为这与冲突无关。@rici
empty
是一个epsilon产品。@Xilpex当然。我会更新我的问题。@miriade\ux:这是一个epsilon产品,当然,我在你的语法列表中看到了。但为什么会在那里?既然您已经发布了源代码,很明显(正如我所怀疑的)归约函数没有任何作用。所以你可以删除它,删除对它的引用,除了语法更紧凑,解析器执行速度更快之外,什么都不会改变。你完全正确!成功了。非常感谢你!
### Write Function ###
def p_write(p):
    '''write : WRITE LPAREN expression_list RPAREN SEMICOLON'''
    p[0] = ('write', p[3])

### Read Function ###
def p_read(p):
    '''read : READ LPAREN expression_list RPAREN SEMICOLON'''
    p[0] = ('read', p[3])


def p_program(p):
    '''program : function'''
    p[0] = p[1]


def p_function(p):
    '''function : identifier identifier formal_parameters block
                | VOID identifier formal_parameters block'''
    p[0] = [p[1], p[2], p[3], p[4]]


def p_formal_parameters(p):
    '''formal_parameters : LPAREN formal_parameter formal_parameters_list RPAREN
                         | LPAREN empty RPAREN'''
    p[0] = p[2]

def p_formal_parameters_list(p):
    '''formal_parameters_list : SEMICOLON formal_parameter formal_parameters_list
                              | empty'''
    if len(p) == 4:
        p[0] = p[3]
        p[0].append(p[2])

    elif len(p) == 2:
        p[0] = [p[1]]

def p_empty(p):
    'empty :'
    pass

def p_formal_parameter(p):
    '''formal_parameter : expression_parameter
                        | function_parameter'''
    p[0] = p[1]

def p_function_parameter(p):
    '''function_parameter : VOID identifier formal_parameters
                          | INTEGER identifier formal_parameters
                          | identifier identifier formal_parameters'''

    p[0] = (p[1], p[2], p[3])

# Mudei um detalhe aqui
def p_expression_parameter(p):
    '''expression_parameter : identifier_list COLON INTEGER
                            | VAR identifier_list COLON INTEGER'''

    if len(p) == 4:
        p[0] = (p[1], p[3])

    elif len(p) == 5:
        p[0] = (p[2], p[4])

def p_identifier_list(p):
    '''identifier_list : identifier
                       | identifier_list COMMA identifier'''
    if len(p) == 4:
        p[0] = p[1]
        p[0].append(p[3])
    elif len(p) == 2:
        p[0] = [p[1]]

def p_block(p):
    '''block : body
             | labels body
             | labels variables body
             | labels variables functions body
             | labels functions body
             | variables body
             | variables functions body
             | functions body'''

    # body
    if len(p) == 2:
        p[0] = p[1]

    # labels body
    # variables body
    # functions body
    elif len(p) == 3:
        p[0] = (p[1], p[2])

    # labels variable body
    # labels functions body
    # variables functions body
    elif len(p) == 4:
        p[0] = (p[1], p[2], p[3])

    #labels variables functions body
    elif len(p) == 5:
        p[0] = (p[1], p[2], p[3], p[4])

def p_functions(p):
    '''functions : FUNCTIONS function_list'''

    p[0] = p[2]

def p_functions_list(p):
    '''function_list  : function 
                      | function function_list'''

    if len(p) == 3:
        p[0] = p[2]
        p[0].append(p[1])

    elif len(p) == 2:
        p[0] = [p[1]]

def p_variables(p):
    '''variables : VARS identifier_list COLON type SEMICOLON'''

    p[0] = (p[2], p[4])

def p_type(p):
    '''type : INTEGER'''
    p[0] = p[1]

def p_labels(p):
    '''labels : LABELS identifier_list SEMICOLON'''
    p[0] = ('labels', p[2])

def p_body(p):
    '''body : LBRACES stamement_list RBRACES '''
    p[0] = p[2]

def p_stamement_list(p):
    '''stamement_list : statement stamement_list
                      | empty'''

    if len(p) == 3:
        p[0] = p[2]
        p[0].append(p[1])

    elif len(p) == 2:
        p[0] = [None]

def p_statement(p):
    '''statement : unlabeled_statement 
                 | compound'''
    p[0] = p[1]

def p_unlabeled_statement(p):
    '''unlabeled_statement : assignment
                           | function_call_statement
                           | goto
                           | return
                           | conditional
                           | repetitive
                           | empty_statement
                           | write
                           | read'''
    p[0] = p[1]


def p_goto(p):
    '''goto : GOTO identifier SEMICOLON'''
    p[0] = ('goto', p[2])

def p_return(p):
    '''return : RETURN return_optional'''
    p[0] = (p[2])

def p_return_optional(p):
    '''return_optional : expression
                       | empty'''
    p[0] = (p[1])

def p_function_call_statement(p):
    '''function_call_statement : function_call SEMICOLON'''
    p[0] = p[1]

def p_function_call(p):
    '''function_call :  IDENTIFIER LPAREN expression_list_and_empty RPAREN'''
    p[0] = (p[1], [p[3]])

def p_expression_list_and_empty(p):
    '''expression_list_and_empty : empty 
                                 | expression_list'''
    p[0] = p[1]

def p_expression_list(p):
    '''expression_list : expression 
                       | expression_list COMMA expression'''

    if len(p) == 4:
        p[0] = p[1]
        p[0].append(p[3])

    elif len(p) == 2:
        p[0] = [p[1]]

def p_repetitive(p):
    '''repetitive : WHILE LPAREN expression RPAREN compound'''
    p[0] = (p[3], p[5])

def p_compound(p):
    '''compound : LBRACES compound_list RBRACES'''
    p[0] = ('{', p[2], '}')

def p_compound_list(p):
    '''compound_list : unlabeled_statement
                     | compound_list unlabeled_statement'''

    if len(p) == 3:
        p[0] = p[1]
        p[0].append(p[2])

    elif len(p) == 2:
        p[0] = [p[1]]


def p_empty_statement(p):
    '''empty_statement : SEMICOLON'''
    p[0] = None


def p_assignment(p):
    '''assignment : identifier EQUALS expression SEMICOLON'''
    p[0] = p[1]


def p_variable(p):
    '''variable : identifier 
                | identifier LBRACKETS expression_list RBRACKETS'''
    p[0] = p[1]

def p_expression(p):
    '''expression : simple_expression expression_optional'''
    p[0] = (p[1], p[2])

def p_expression_optional(p):
    '''expression_optional : relational_operator simple_expression
                           | empty'''

    if len(p) == 3:
        p[0] = (p[1], p[2])

    if len(p) == 2:
        p[0] = None

def p_relational_operator(p):
    '''relational_operator : COMPAREEQUAL
                           | NOTEQQUAL
                           | LESS 
                           | LESSEQUAL
                           | GREATQUAL
                           | GREAT'''

    p[0] = p[1]


def p_conditional(p):
    '''conditional : IF LPAREN expression RPAREN compound 
                   | IF LPAREN expression RPAREN compound ELSE compound'''

    if len(p) == 6:
        p[0] = ('IF', p[3], p[5])

    if len(p) == 8:
        p[0] = ('IF', p[3], p[5], 'ELSE', p[7])


def p_simple_expression(p):
    '''simple_expression : term simple_expression_list'''
    p[0] = (p[1], p[2])

def p_simple_expression_list(p):
    '''simple_expression_list : additive_operator term simple_expression_list
                              | empty '''

    if len(p) == 4:
        p[0] = p[3]
        p[0].append( (p[1], p[2]) )

    elif len(p) == 2:
        p[0] = [None]

def p_additive_operator(p):
    '''additive_operator : PLUS 
                         | MINUS'''
    p[0] = p[1]

def p_term(p):
    '''term : factor multiplicative_operator_list'''
    p[0] = p[1]

def p_multiplicative_operator(p):
    '''multiplicative_operator : TIMES
                               | DIVIDE'''
    p[0] = p[1]

def p_multiplicative_operator_list(p):
    '''multiplicative_operator_list : multiplicative_operator factor multiplicative_operator_list
                                    | empty'''

    if len(p) == 4:
        p[0] = p[3]
        p[0].append( (p[1], p[2]) )

    elif len(p) == 2:
        p[0] = [None]

def p_factor(p):
    '''factor : NUMBER
              | variable
              | LPAREN expression RPAREN
              | function_call'''

    p[0] = p[1]

def p_identifier(p):
    '''identifier : IDENTIFIER'''
    p[0] = p[1]

def p_error(p):
    print("Error", p)