• LR编写grammar中的问题和解决方法


    本文主要说明LR解析过程中关于BNF的典型冲突如何在LR中解决

    冲突一般分为两种:

    • shift/reduce错误
    • redure/redure错误

    下面分别解释两种冲突

    1. shift/reduce错误

        这种错误是因为 分析器在这种情况下不知道是归约还是移进导致的。

    2. redure/redure错误

        这种错误是因为,解析器在解析栈中规则时发现有多个规则可以进行归约。rejected rule 会指出跟哪个rule冲突

    我们首先举个例子。

    例子1

    文法如下: 这是一个简单的解析

    "<><><><>"

    "<>"

    ""

    class classnam {}

    def p_start(p):
        '''
            start : typeArguments
        '''
    
    def p_typeArguments(p):
        '''
            typeArguments : typeArgument
            | typeArguments typeArgument
        '''
    
    def p_typeArgument(p):
        '''
            typeArgument : LESS MORE
            | empty
        '''
    
    def p_empty( p ):
        '''empty : '''
    

    这时产生的错误。

    WARNING: 
    WARNING: Conflicts:
    WARNING: 
    WARNING: shift/reduce conflict for LESS in state 0 resolved as shift
    WARNING: shift/reduce conflict for LESS in state 2 resolved as shift
    WARNING: reduce/reduce conflict in state 2 resolved using rule (start -> typeArguments)
    WARNING: rejected rule (empty -> <empty>) in state 2
    

    那么下面看看如何来解决这个问题。

    def p_start(p):
        '''
            start : typeArguments
            | empty
        '''
    
    def p_typeArguments(p):
        '''
            typeArguments : typeArgument
            | typeArguments typeArgument
        '''
    
    def p_typeArgument(p):
        '''
            typeArgument : LESS MORE
        '''
    
    def p_empty( p ):
        '''empty : '''
    

    这个问题出现在

    def p_typeArgument(p):
        '''
            typeArgument : LESS MORE
            | empty
        '''
    

    身上,因为empty比较特殊可以告诉yacc可以reduce,因为结束了。而LESS还需要shift.

    而在 typeArgument 身上也出现了一个问题就是到底 typeArgument是redure成empty还是 LESS MORE形式。

    例子2

    def p_start(p):
        '''
            start : typeArguments
        '''
    
    def p_typeArguments(p):
        '''
            typeArguments : typeArgument
            | typeArguments typeArgument
        '''
    
    def p_typeArgument(p):
        '''
            typeArgument : LESS MORE
            | list
        '''
    
    def p_list(p):
        '''
            list : LESS MORE
        '''
    
    def p_empty( p ):
        '''empty : '''
    

    这个问题是比较典型的redure冲突

    出现在 typeArgument和list的冲突上。

    WARNING: 
    WARNING: Conflicts:
    WARNING: 
    WARNING: reduce/reduce conflict in state 7 resolved using rule (typeArgument -> LESS MORE)
    WARNING: rejected rule (list -> LESS MORE) in state 7
    WARNING: Rule (list -> LESS MORE) is never reduced
    

    这种情况就是因为在一个规则树中出现了两个同样的规则在同一个里面。

    例子3

    这个例子算是一个较为经典的shift/redure的问题。

    expression : expression PLUS expression
           | expression MINUS expression
           | expression TIMES expression
           | expression DIVIDE expression
           | LPAREN expression RPAREN
           | NUMBER
    

    如果我们不只用优先级来定义,那么我们可以如下方法解决优先级别的问题:

    def p_start(p):
        '''
            start : expression
        '''
    
    def p_expression(p):
        '''
            expression : multExpression
            | expression PLUS multExpression
            | expression MINUS multExpression
        '''
    
    def p_multExpression(p):
        '''
            multExpression : subExpression
            | multExpression TIMES subExpression
            | multExpression DIVIDE subExpression
        '''
    
    def p_subExpression(p):
        '''
            subExpression :  LPAREN expression RPAREN
            | primary
        '''
    
    def p_primary(p):
        '''
            primary : NUMBER
        '''
    

    在java中也可以使用如上方法来定义一个expression来完成整个expression树的解析过程。因为过于复杂,所以这里不就写了,有兴趣的可以看java 7 lanaguage

    上面3个例子都比较典型,基本能把大部分书写LR文法的时候遇到的问题解决掉。

    参考:https://www.ituring.com.cn/article/52229

  • 相关阅读:
    Linux kill, killall, kill -9
    mongodb分片集群(无副本集)搭建
    如何用vs查看结构体布局
    Winsock在Windows下的编程教程(C语言)(图文并茂,超长教程)
    HTTPS 中双向认证SSL 协议的具体过程
    RAR压缩解压命令
    x64栈结构
    ASP.NET Web API下的HttpController激活:程序集的解析
    Lucene学习-深入Lucene分词器,TokenStream获取分词详细信息
    IO多路复用之select
  • 原文地址:https://www.cnblogs.com/davygeek/p/11971319.html
Copyright © 2020-2023  润新知