zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    以一道CTF题目看无参数RCE
    浅谈php序列化字符串逃逸问题
    [XCTF 4th] ics-05 复现
    关于Sharp俩打印机AR-1808S和AR-2348SV的共享问题
    关于使用AdventureWorks2008示例数据库之初碰到的问题
    明日科技的SQL Server---6
    ado.net 4 step by step随书数据库
    手欠,大半个下午加一晚上就报销了。
    程序员的SQL金典
    c#读写文件
  • 原文地址:https://www.cnblogs.com/davygeek/p/11971319.html
Copyright © 2011-2022 走看看