0
回答
python 的解析器 ply 疑难问题
滴滴云服务器,限时包月0.9元,为开发者而生>>>   

我想对c语言进行解析,获取C语言中各个参数的取值范围和数据

但是这个过程中由于对于变异原理不是很理解,出现很多问题,下面是我检测全局变量定义处的代码,各位大大看看,应该怎么修改:

注:结果色字体部分是存储的类型错误,此时情形是p : p[1]为error ,p[1]的value的值等于P[2]所以出错。

其实我对于怎么使用''' '''这个里面的语言影响 yacc中解析器的执行顺序不是很明白。

        yacc源代码:

        while True:
            # Get the next symbol on the input.  If a lookahead symbol
            # is already set, we just use that. Otherwise, we'll pull
            # the next token off of the lookaheadstack or from the lexer
            if state not in defaulted_states:
                if not lookahead:
                    if not lookaheadstack:
                        lookahead = get_token()     # Get the next token
                    else:
                        lookahead = lookaheadstack.pop()
                    if not lookahead:
                        lookahead = YaccSymbol()
                        lookahead.type = '$end'


                # Check the action table
                ltype = lookahead.type
                t = actions[state].get(ltype)
            else:
                t = defaulted_states[state]

    有时候lookahead匹配得到的t是的lookahead直接入栈,有的是先处理后入栈,已经晕了

我的parser代码

class Find_All_Global():
    tokens = MyLexer.tokens
    type_flag = 0
    tmp_type = ''
    def __init__(self):
        self.type_flag = 0 
        self.tmp_type = ''
        
            
    def p_get_Golbal_Var_name(self,p):
        '''g_name : type NAME ASSIGNMENT
                  | type NAME SEMICOLON
                  | error NAME ASSIGNMENT
                  | error NAME SEMICOLON
                  '''
        if self.type_flag == 0 and len(p) == 4:
            for i in range(len(typedef_name)):
                if typedef_name[i] == str(p[2]):
                    #print typedef_name[i]
                    return 1
            if p[0] != '':
                p[0] = p[2]
                print p[0],p.lineno(1),self.type_flag,p[1]
                file_message.Global_Varible_Name.append(p[0])
                file_message.Global_Varible_Type.append(p[1].value)
                self.tmp_type = ''
        elif self.type_flag == 1 and len(p) == 4 :
            p[0] = p[2]
            print '补漏',p[0]
            file_message.Global_Varible_Name.append(p[0])
            file_message.Global_Varible_Type.append(self.tmp_type)
            self.tmp_type = ''
            self.type_flag = 0
        elif len(p) == 5 :
            p[0] = p[3]
            print "len == 5",p[0]
            
    def p_typename(self,p):
        '''type : tdef_name
                | type_name
                '''
        p[0] = p[1]
        p.set_lineno(0,p.lineno(1))  #行号传递
    
    def p_compare_typedef(self,p):
        '''tdef_name : NAME'''
        for i in range(len(typedef_name)):
            if typedef_name[i] == str(p[1]):
                p[0] = p[1]
                p.set_lineno(0,p.lineno(1))
                #print typedef_name[i],p.lineno(1)
                break
            if i == len(typedef_name)-1:
                p[0] = ''
                return 1


    def p_type_name(self, p):
        '''type_name : VOID
                     | CHAR
                     | SIGNED CHAR
                     | UNSIGNED CHAR
                     | INT
                     | SIGNED INT
                     | UNSIGNED INT
                     | SHORT
                     | SIGNED SHORT
                     | UNSIGNED SHORT
                     | LONG
                     | SIGNED LONG
                     | UNSIGNED LONG
                     | LONG LONG
                     | UNSIGNED LONG LONG
                     '''
        if len(p) == 2:
            p[0] =  p[1]
        elif len(p) == 3:
            p[0] = p[1] + ' ' + p[2]
        elif len(p) == 4:
            p[0] = p[1] + ' ' + p[2] + ' ' + p[3]
        p.set_lineno(0,p.lineno(1))
        print ' type_name :%s' % str(p[0])
    
    def p_error(self, p):
        '''type : error'''
#         print('error: {}'.format(p))
#         yacc.restart()
        #print "error : %s,%s,%d" % (p.type,p.value,p.lineno)
        # 无法传递参数或者数据给其他数据,error中只有一个P,不能写p[0] or p[1]
        #print "error" , format(p)
        for i in range(len(typedef_name)):
            if typedef_name[i] == str(p.value) and self.type_flag == 0 :
                self.type_flag = 1
                self.tmp_type = p.value
                print  self.type_flag,p.value,p.lineno
                #给标志位赋值
                #print typedef_name[i],p.lineno(1)
                return 1   
        self.type_flag = 0
        #raise SyntaxError
        #print yacc.token().value


    def p_empty(self, p):
        '''empty :'''


运行结果如下:

<type 'instance'>
gubGhufeng 39 0  LexToken(INT,'int',39,967)
name_hu 40 0 LexToken(CHAR,'char',40,983)
line_li 41 0  LexToken(SHORT,'short',41,997)
test_glb 43 0  LexToken(NAME,'test_glb',43,1017)
1 u32 45
补漏 guwTestCode2
guwCodeTest 46 0 胡峰 LexToken(NAME,'guwCodeTest',46,1064)
gubConstNum 47 0 胡峰 LexToken(NAME,'gubConstNum',47,1087)
1 u8 48
补漏 gubNumConst1
guwTestCode1 49 0  LexToken(STATIC,'static',49,1127)
guwRegMax 51 0  LexToken(NAME,'guwRegMax',51,1153)
1 u8 53
补漏 gubStackNum
1 u8 55
补漏 gubRegCount
1 u8 57
补漏 guwEdgeAreaA
1 u16 61
补漏 guwEdgeAreaB
14 ['gubGhufeng', 'name_hu', 'line_li', 'test_glb', 'guwTestCode2', 'guwCodeTest', 'gubConstNum', 'gubNumConst1', 'guwTestCode1', 'guwRegMax', 'gubStackNum', 'gubRegCount', 'guwEdgeAreaA', 'guwEdgeAreaB']
14 ['int', 'char', 'short', 'test_glb', 'u32', 'guwCodeTest', 'gubConstNum', 'u8', 'static', 'guwRegMax', 'u8', 'u8', 'u8', 'u16']

举报
miss失舵
发帖于2年前 0回/211阅
顶部