python 에서 protobuf 파일 을 분석 하 는 간단 한 컴 파일 러 를 개발 합 니 다.

머리말
최근 에 python 으로 protobuf 파일 을 분석 하 는 간단 한 컴 파일 러 를 썼 습 니 다.ply 는 품사 분석 과 문법 분석 을 간결 하고 편리 하 게 실현 하 는 것 을 느 꼈 습 니 다.여열 이 지나 지 않 은 틈 을 타서 머리 가 맑 고 정리 와 소감 을 적어 서 여러분 의 pythoner 가 참고 하여 사용 하기에 편리 합 니 다.
ply 사용
간단 한 소개
컴 파일 러 나 해석 기 개발 에 종사 하지 않 았 다 면 ply 를 들 어 본 적 이 없 었 을 것 이다.ply 는 python 의 lex 와 Ycc 를 기반 으로 하 며,그 작 가 는 유명한 Python Cookbook,3rd Edition 의 작가 입 니 다.어떤 친구 들 은 궁금 해 할 것 이다.내 업무 개발 에 어떻게 스스로 컴 파일 러 를 써 야 하 는 지,여러분 의 프로 그래 밍 소 들 은 중앙 에서 결정 하고 새로운 것 을 많이 시도 해 야 한다 고 말 했다.그리고 문법 해석 자 세 를 알 아 보고 복잡 한 로그 나 수학 공식 을 스스로 해석 하 는 것 도 도움 이 된다.
컴 파일 기반 이 없 는 어린이 신발 에 대해 문법 과 관련 된 기본 개념 을 알 아 보 는 것 을 강력 히 권장 합 니 다.바퀴 형 이 강력 히 추천 하 는 parsing techniques 와 용 호 고래 책 을 번역 하 는 것 은 개인 적 으로 입문 학습 에 적합 하지 않다 고 생각 합 니 다.여기 서 후 룬 준 의 컴 파일 원리(전자 공업 출판사)를 추천 합 니 다.개념 에 대한 예 를 많이 설명 하여 입문 학습 에 적합 합 니 다.물론 특별히 깊이 연구 할 필요 도 없고 문법 분석 과 문법 분석의 관련 개념 과 방법 을 알 면 ply 를 즐겁게 사용 할 수 있다.문서 링크:http://www.pchou.info/open-source/2014/01/18/52da47204d4cb.html
여러분 의 편 의 를 위해 다 원 화 된 방정식 팀 을 예 로 들 어 ply 의 사용 을 설명 합 니 다.
예 설명
입력 은 여러 형식 이 x+4y-3.2z=7 인 일차 방정식 입 니 다.예 를 가능 한 한 간단하게 하기 위해 다음 과 같은 제한 을 합 니 다.
  • 각 방정식 에 변 수 를 포함 하 는 부분 은 등호 왼쪽 에 있 고 상 수 는 등호 오른쪽
  • 에 있다.
  • 각 방정식 은 변수의 개수 와 변수의 순 서 를 제한 하지 않 지만 각 방정식 의 매개 변 수 는 한 번 만 나타 날 수 있다
  • .
  • 변수의 명령 규칙 은 소문 자 문자열(x y xx yy abc 는 모두 합 법 적 인 변수 이름)
  • 입 니 다.
  • 변수의 계 수 는 정수 와 부동 소수점 으로 제한 되 고 부동 소수점 은 1.4e 8 의 형식 을 허용 하지 않 으 며 계수 와 변수 가 인접 하 며 계 수 는 0
  • 이 될 수 없다.
  • 방정식 팀 과 방정식 팀 간 에 사용 합 니 다.간막이
  • 선형 대 수 를 배 운 동 화 는 방정식 을 행렬 로 추상 화하 고 선형 대수 적 방법 에 따라 해결 할 수 있다 는 것 을 분명히 알 고 있 을 것 이다.따라서 입력 방정식 그룹 을 오른쪽 매트릭스 와 변수 목록 으로 해석 하면 되 고 나머지 구 해 과정 은 선형 대수 와 관련 된 도구 로 해결 할 수 있다.

    어법 해석
    ply 에서 lex 는 품사 해석 을 하 는데 품사 해석 이론 이 많 지만 lex 는 사용 하기에 매우 직관 적 입 니 다.바로 정규 표현 식 으로 텍스트 문자열 을 하나의 token 으로 해석 하 는 것 입 니 다.아래 코드 는 lex 로 품사 해석 을 실현 하 는 것 입 니 다.
    
    from ply import lex
    
    #                    
    t_ignore = ' \t\r'
    
    #              
    def t_error(t):
      raise Exception('error {} at line {}'.format(t.value[0], t.lineno))
    
    #     ,      
    def t_newline(t):
      r'
    +' t.lexer.lineno += len(t.value) # c++ \\ def t_ignore_COMMENT(t): r'\/\/[^
    ]*' # def t_VARIABLE(t): r'[a-z]+' return t # def t_CONSTANT(t): r'\d+(\.\d+)?' t.value = float(t.value) return t # token, t_PLUS = r'\+' token literals = '+-,;=' tokens = ('VARIABLE', 'CONSTANT') if __name__ == '__main__': data = ''' -x + 2.4y + z = 0; //this is a comment 9y - z + 7.2x = -1; y - z + x = 8 ''' lexer = lex.lex() lexer.input(data) while True: tok = lexer.token() if not tok: break print tok
    파일 을 직접 실행 하면 해 석 된 token 문자열 을 인쇄 할 수 있 습 니 다.아래 와 같이 상세 한 사용 문 서 는 ply 문 서 를 참고 할 수 있 습 니 다.
    
    LexToken(-,'-',2,5)
    LexToken(VARIABLE,'x',2,6)
    LexToken(+,'+',2,8)
    LexToken(CONSTANT,2.4,2,10)
    LexToken(VARIABLE,'y',2,13)
    LexToken(+,'+',2,15)
    LexToken(VARIABLE,'z',2,17)
    LexToken(=,'=',2,19)
    LexToken(CONSTANT,0.0,2,21)
    LexToken(;,';',2,22)```
    
    ###     
    
    ply  yacc      ,                    ,                        。   yacc  ,           ,         ,            ,                 。
    
                 ,                    。                      ,                    ,   ,     ,       ,             。     LL(1),           ,          ,           。                  ,            ,            ,            ,      ,             。     SLR、LRLR,ply     LRLR。
    
                      ,         。
    
    ```python
    # -*- coding=utf8 -*-
    
    from ply import (
      lex,
      yacc
    )
    
    #                    
    t_ignore = ' \t\r'
    
    #              
    def t_error(t):
      raise Exception('error {} at line {}'.format(t.value[0], t.lineno))
    
    #     ,      
    def t_newline(t):
      r'
    +' t.lexer.lineno += len(t.value) # c++ \\ def t_ignore_COMMENT(t): r'\/\/[^
    ]*' # def t_VARIABLE(t): r'[a-z]+' return t # def t_CONSTANT(t): r'\d+(\.\d+)?' t.value = float(t.value) return t # token, t_PLUS = r'\+' token literals = '+-,;=' tokens = ('VARIABLE', 'CONSTANT') # , equations p[1] , def p_start(p): """start : equations""" var_count, var_list = 0, [] for left, _ in p[1]: for con, var_name in left: if var_name in var_list: continue var_list.append(var_name) var_count += 1 matrix = [[0] * (var_count + 1) for _ in xrange(len(p[1]))] for counter, eq in enumerate(p[1]): left, right = eq for con, var_name in left: matrix[counter][var_list.index(var_name)] = con matrix[counter][-1] = -right var_list.append(1) p[0] = matrix, var_list # , , ; def p_equations(p): """equations : equation ',' equations | equation ';' equations | equation""" if len(p) == 2: p[0] = [p[1]] else: p[0] = [p[1]] + p[3] # def p_equation(p): """equation : eq_left '=' eq_right""" p[0] = (p[1], p[3]) # def p_eq_left(p): """eq_left : var_unit eq_left |""" if len(p) == 1: p[0] = [] else: p[0] = [p[1]] + p[2] # : x, 5x, +x, -x, +4x, -4y # , : (5, 'x') def p_var_unit(p): """var_unit : VARIABLE | CONSTANT VARIABLE | '+' VARIABLE | '-' VARIABLE | '+' CONSTANT VARIABLE | '-' CONSTANT VARIABLE""" len_p = len(p) if len_p == 2: p[0] = (1.0, p[1]) elif len_p == 3: if p[1] == '+': p[0] = (1.0, p[2]) elif p[1] == '-': p[0] = (-1.0, p[2]) else: p[0] = (p[1], p[2]) else: if p[1] == '+': p[0] = (p[2], p[3]) else: p[0] = (-p[2], p[3]) # , :1.2, +1.2, -1.2 def p_eq_right(p): """eq_right : CONSTANT | '+' CONSTANT | '-' CONSTANT""" if len(p) == 3: if p[1] == '-': p[0] = -p[2] else: p[0] = p[2] else: p[0] = p[1] if __name__ == '__main__': data = ''' -x + 2.4y + z = 0; //this is a comment 9y - z + 7.2x = -1; y - z + x = 8 ''' lexer = lex.lex() parser = yacc.yacc(debug=True) lexer.lineno = 1 s = parser.parse(data) print s
    파일 을 직접 실행 하면 됩 니 다.출력 은 다음 과 같 습 니 다.그 다음 에 선형 대수 방법 에 따라 각 변수의 값 을 구 할 수 있 습 니 다.
    ([[-1.0, 2.4, 1.0, -0.0], [7.2, 9.0, -1.0, 1.0], [1.0, 1.0, -1.0, -8.0]], ['x', 'y', 'z', 1])
    총결산
    python 의 간결 한 문법 을 바탕 으로 ply 는 우리 에 게 강력 한 문법 분석 도 구 를 제공 합 니 다.더욱 복잡 한 예 는 참고 할 수 있 습 니 다https://github.com/LiuRoy/proto_parser.이것 은 제 가 ply 로 실현 한 간단 한 protobuf 해석 기 입 니 다.빈번 한 중간 파일 생 성 을 줄 이 는 데 사 용 됩 니 다.이런 신기 가 있 습 니 다.조정 하나!
    이상 은 python 이 protobuf 파일 을 분석 하 는 간단 한 컴 파일 러 를 개발 하 는 상세 한 내용 입 니 다.python 개발 컴 파일 러 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!

    좋은 웹페이지 즐겨찾기