Parsing Lemon解析器:此规则无法简化

Parsing Lemon解析器:此规则无法简化,parsing,grammar,lalr,lemon,Parsing,Grammar,Lalr,Lemon,我正试图编写语法来解析模板语言say(或由您选择),但我无法成功解析switch case语句 让我展示一下所需的语法: {% switch username %} {% case "Jim" %} I want to say: {% case "Nik" %} Hello man! {% endcase %} {% case "Bob" %} Hi {% default %} Who ar

我正试图编写语法来解析模板语言say(或由您选择),但我无法成功解析
switch case
语句

让我展示一下所需的语法:

{% switch username %}
    {% case "Jim" %}
        I want to say: 
    {% case "Nik" %}
        Hello man!
    {% endcase %}
    {% case "Bob" %}
        Hi
    {% default %}
        Who are you?
{% endswitch %}
在这里,endcase只是起到了break的作用

我的语法文件的工作部分:

program ::= template_language(Q) . {
    status->ret = Q;
}

template_language(R) ::= statement_list(L) . {
    R = L;
}

statement_list(R) ::= statement_list(L) statement(S) . {
    R = my_list(L, S);
}

statement_list(R) ::= statement(S) . {
    R = my_list(NULL, S);
}

statement(R) ::= switch_statement(E) . {
    R = E;
}

// empty {% switch expr %} {% endswitch %}
switch_statement(R) ::= OPEN_DELIMITER SWITCH expr(E) CLOSE_DELIMITER OPEN_DELIMITER ENDSWITCH CLOSE_DELIMITER . {
    R = my_switch_statement(E, NULL, status->scanner_state);
}

switch_statement(R) ::= OPEN_DELIMITER SWITCH expr(E) CLOSE_DELIMITER case_clauses(C) OPEN_DELIMITER ENDSWITCH CLOSE_DELIMITER . {
    R = my_switch_statement(E, C, status->scanner_state);
}

case_clauses(R) ::= case_clauses(C) case_clause(K) . {
    R = my_list(C, K);
}

case_clauses(R) ::= case_clause(K) . {
    R = my_list(NULL, K);
}

// empty {% case expr %} {% endcase %}
case_clause(R) ::= OPEN_DELIMITER CASE expr(E) CLOSE_DELIMITER OPEN_DELIMITER ENDCASE CLOSE_DELIMITER . {
    R = case_clause(E, NULL, status->scanner_state);
}

case_clause(R) ::= OPEN_DELIMITER CASE expr(E) CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ENDCASE CLOSE_DELIMITER . {
    R = case_clause(E, T, status->scanner_state);
}
这只是我语法的一部分,我曾为
for
if
while
do
loop
等工作过语法

但我不知道:

  • {%case expr%}语句\u列表(T)
    不带
    {%endcase%}
  • {%default%}语句\u列表(T)
  • 例如,我尝试使用:

    case_clause(R) ::= OPEN_DELIMITER CASE expr(E) CLOSE_DELIMITER statement_list(T) . {
        R = case_clause(E, T, status->scanner_state);
    }
    
    1次,但运气不好,明白吗

    这条规则不能简化

    #2也一样

    坦率地说,我理解问题的根源——缺乏案例/违约界限,但实际上我不知道如何解决这个问题


    任何帮助都将不胜感激

    问题是你的语法是LR(2),而不是LR(1)

    许多移位/减少冲突出现,因为直到出现了代码> %{ >之后才知道该怎么做。例如,考虑部分模板(我故意破坏了缩进):


    作为旁注,我建议简化语法,不要对空语句列表使用特殊的大小写。只需为
    语句列表
    使用空的基本大小写即可:

    program ::= template_language(Q) . {
        status->ret = Q;
    }
    
    template_language(R) ::= statement_list(L) . {
        R = L;
    }
    
    statement_list(R) ::= statement_list(L) statement(S) . {
        R = my_list(L, S);
    }
    
    statement_list(R) ::= . {
        R = NULL;
    }
    
    statement(R) ::= switch_statement(E) . {
        R = E;
    }
    
    switch_statement(R) ::= OPEN_SWITCH expr(E) CLOSE case_clauses(C) OPEN_ENDSWITCH CLOSE . {
        R = my_switch_statement(E, C, status->scanner_state);
    }
    
    case_clauses(R) ::= case_clauses(C) case_clause(K) . {
        R = my_list(C, K);
    }
    
    case_clauses(R) ::= . {
        R = NULL;
    }
    
    case_clause(R) ::= OPEN_CASE expr(E) CLOSE statement_list(T) OPEN_ENDCASE CLOSE . {
        R = case_clause(E, T, status->scanner_state);
    }
    
    case_clause(R) ::= OPEN_CASE expr(E) CLOSE statement_list(T) . {
        R = case_clause(E, T, status->scanner_state);
    }
    
    case_clause(R) ::= OPEN_DEFAULT CLOSE statement_list(T) . {
        R = case_clause(E, T, status->scanner_state);
    }
    

    问题是你的语法是LR(2),而不是LR(1)

    许多移位/减少冲突出现,因为直到出现了代码> %{ >之后才知道该怎么做。例如,考虑部分模板(我故意破坏了缩进):


    作为旁注,我建议简化语法,不要对空语句列表使用特殊的大小写。只需为
    语句列表
    使用空的基本大小写即可:

    program ::= template_language(Q) . {
        status->ret = Q;
    }
    
    template_language(R) ::= statement_list(L) . {
        R = L;
    }
    
    statement_list(R) ::= statement_list(L) statement(S) . {
        R = my_list(L, S);
    }
    
    statement_list(R) ::= . {
        R = NULL;
    }
    
    statement(R) ::= switch_statement(E) . {
        R = E;
    }
    
    switch_statement(R) ::= OPEN_SWITCH expr(E) CLOSE case_clauses(C) OPEN_ENDSWITCH CLOSE . {
        R = my_switch_statement(E, C, status->scanner_state);
    }
    
    case_clauses(R) ::= case_clauses(C) case_clause(K) . {
        R = my_list(C, K);
    }
    
    case_clauses(R) ::= . {
        R = NULL;
    }
    
    case_clause(R) ::= OPEN_CASE expr(E) CLOSE statement_list(T) OPEN_ENDCASE CLOSE . {
        R = case_clause(E, T, status->scanner_state);
    }
    
    case_clause(R) ::= OPEN_CASE expr(E) CLOSE statement_list(T) . {
        R = case_clause(E, T, status->scanner_state);
    }
    
    case_clause(R) ::= OPEN_DEFAULT CLOSE statement_list(T) . {
        R = case_clause(E, T, status->scanner_state);
    }
    
    {% switch username %} {% case "Jim" %} I want to say: {% case
    {% switch username %} {% case "Jim" %} I want to say: {% switch
    program ::= template_language(Q) . {
        status->ret = Q;
    }
    
    template_language(R) ::= statement_list(L) . {
        R = L;
    }
    
    statement_list(R) ::= statement_list(L) statement(S) . {
        R = my_list(L, S);
    }
    
    statement_list(R) ::= statement(S) . {
        R = my_list(NULL, S);
    }
    
    statement(R) ::= switch_statement(E) . {
        R = E;
    }
    
    // empty {% switch expr %} {% endswitch %}
    switch_statement(R) ::= OPEN_SWITCH expr(E) CLOSE OPEN_ENDSWITCH CLOSE . {
        R = my_switch_statement(E, NULL, status->scanner_state);
    }
    
    switch_statement(R) ::= OPEN_SWITCH expr(E) CLOSE case_clauses(C) OPEN_ENDSWITCH CLOSE . {
        R = my_switch_statement(E, C, status->scanner_state);
    }
    
    case_clauses(R) ::= case_clauses(C) case_clause(K) . {
        R = my_list(C, K);
    }
    
    case_clauses(R) ::= case_clause(K) . {
        R = my_list(NULL, K);
    }
    
    // empty {% case expr %} {% endcase %}
    case_clause(R) ::= OPEN_CASE expr(E) CLOSE OPEN_ENDCASE CLOSE . {
        R = case_clause(E, NULL, status->scanner_state);
    }
    
    case_clause(R) ::= OPEN_CASE expr(E) CLOSE statement_list(T) OPEN_ENDCASE CLOSE . {
        R = case_clause(E, T, status->scanner_state);
    }
    
    case_clause(R) ::= OPEN_CASE expr(E) CLOSE statement_list(T) . {
        R = case_clause(E, T, status->scanner_state);
    }
    
    
    case_clause(R) ::= OPEN_DEFAULT CLOSE statement_list(T) . {
        R = case_clause(E, T, status->scanner_state);
    }
    
    program ::= template_language(Q) . {
        status->ret = Q;
    }
    
    template_language(R) ::= statement_list(L) . {
        R = L;
    }
    
    statement_list(R) ::= statement_list(L) statement(S) . {
        R = my_list(L, S);
    }
    
    statement_list(R) ::= . {
        R = NULL;
    }
    
    statement(R) ::= switch_statement(E) . {
        R = E;
    }
    
    switch_statement(R) ::= OPEN_SWITCH expr(E) CLOSE case_clauses(C) OPEN_ENDSWITCH CLOSE . {
        R = my_switch_statement(E, C, status->scanner_state);
    }
    
    case_clauses(R) ::= case_clauses(C) case_clause(K) . {
        R = my_list(C, K);
    }
    
    case_clauses(R) ::= . {
        R = NULL;
    }
    
    case_clause(R) ::= OPEN_CASE expr(E) CLOSE statement_list(T) OPEN_ENDCASE CLOSE . {
        R = case_clause(E, T, status->scanner_state);
    }
    
    case_clause(R) ::= OPEN_CASE expr(E) CLOSE statement_list(T) . {
        R = case_clause(E, T, status->scanner_state);
    }
    
    case_clause(R) ::= OPEN_DEFAULT CLOSE statement_list(T) . {
        R = case_clause(E, T, status->scanner_state);
    }