문제

나는 파이썬에서 토큰 화기를 구현할 것입니다. 스타일의 조언을 제공 할 수 있는지 궁금합니다.

나는 C와 Java에서 이전에 토큰 화기를 구현 했으므로 이론에 괜찮습니다. 나는 Pythonic 스타일과 모범 사례를 따르고 있는지 확인하고 싶습니다.

목록 토큰 유형 :

예를 들어 Java에서는 다음과 같은 필드 목록이 있습니다.

public static final int TOKEN_INTEGER = 0

그러나 분명히, 파이썬에서 일정한 변수를 선언 할 방법은 없으므로 이것을 정상적인 변수 선언으로 바꿀 수는 있지만 선언이 변경 될 수 있기 때문에 훌륭한 솔루션으로 나갈 수는 없습니다.

토큰 화기에서 토큰 반환 :

단순히 튜플 목록을 반환하는 더 좋은 대안이 있습니까?

[ (TOKEN_INTEGER, 17), (TOKEN_STRING, "Sixteen")]?

건배,

피트

도움이 되었습니까?

해결책

Python은 정보 숨기기에 대한 "우리 모두 동의하는 성인"접근 방식을 취합니다. 변수가 상수 인 것처럼 변수를 사용해도 괜찮습니다. 코드 사용자가 어리석은 일을하지 않을 것이라고 믿습니다.

다른 팁

문서화되지 않은 클래스가 있습니다 re 모듈이 호출되었습니다 re.Scanner. 토큰 화기에 사용하는 것은 매우 간단합니다.

import re
scanner=re.Scanner([
  (r"[0-9]+",       lambda scanner,token:("INTEGER", token)),
  (r"[a-z_]+",      lambda scanner,token:("IDENTIFIER", token)),
  (r"[,.]+",        lambda scanner,token:("PUNCTUATION", token)),
  (r"\s+", None), # None == skip token.
])

results, remainder=scanner.scan("45 pigeons, 23 cows, 11 spiders.")
print results

결과가 나옵니다

[('INTEGER', '45'),
 ('IDENTIFIER', 'pigeons'),
 ('PUNCTUATION', ','),
 ('INTEGER', '23'),
 ('IDENTIFIER', 'cows'),
 ('PUNCTUATION', ','),
 ('INTEGER', '11'),
 ('IDENTIFIER', 'spiders'),
 ('PUNCTUATION', '.')]

Re.Scanner를 사용하여 꽤 멋진 구성/구조화 된 데이터 형식 파서를 수백 줄로 작성했습니다.

많은 상황에서 Exp. 긴 입력 스트림을 구문 분석 할 때 발전기 기능으로 토 케이저를 구현하는 것이 더 유용 할 수 있습니다. 이렇게하면 먼저 토큰 목록을 구축하기 위해 많은 메모리가 필요하지 않고 모든 토큰을 쉽게 반복 할 수 있습니다.

발전기를 참조하십시오 원래 제안 또는 다른 온라인 문서

도움을 주셔서 감사합니다.이 아이디어를 하나로 모으기 시작했고 다음을 생각해 냈습니다. 이 구현에 큰 문제가 있습니까 (특히 파일 개체를 토큰 화기에 전달하는 것이 걱정됩니다).

class Tokenizer(object):

  def __init__(self,file):
     self.file = file

  def __get_next_character(self):
      return self.file.read(1)

  def __peek_next_character(self):
      character = self.file.read(1)
      self.file.seek(self.file.tell()-1,0)
      return character

  def __read_number(self):
      value = ""
      while self.__peek_next_character().isdigit():
          value += self.__get_next_character()
      return value

  def next_token(self):
      character = self.__peek_next_character()

      if character.isdigit():
          return self.__read_number()

"단순히 튜플 목록을 반환하는 더 좋은 대안이 있습니까?"

아니요. 정말 잘 작동합니다.

"단순히 튜플 목록을 반환하는 더 좋은 대안이 있습니까?"

이것이 Python 소스 코드를 구문 분석하기 위해 "Tokenize"모듈에서 사용하는 접근법입니다. 간단한 튜플 목록을 반환하는 것은 매우 잘 작동 할 수 있습니다.

나는 최근에 토큰 화기도 만들었고 당신의 몇 가지 문제를 통과했습니다.

토큰 유형은 모듈 레벨에서 "상수", 즉 all_caps 이름을 가진 변수로 선언됩니다. 예를 들어,

_INTEGER = 0x0007
_FLOAT = 0x0008
_VARIABLE = 0x0009

등등. 나는 이름 앞에서 밑줄을 사용하여 그 필드가 모듈에 대해 "개인"이라는 것을 지적했지만, 이것이 전형적이거나 권한이 있는지, 심지어 얼마나 많은 피스닉이 아닌지는 모르겠습니다. (또한, 디버깅 중에는 훨씬 더 읽기 쉬워서 문자열에 유리하게 숫자를 버릴 것입니다.)

토큰은 명명 된 튜플로 반환됩니다.

from collections import namedtuple
Token = namedtuple('Token', ['value', 'type'])
# so that e.g. somewhere in a function/method I can write...
t = Token(n, _INTEGER)
# ...and return it properly

Tokenizer의 클라이언트 코드 (예 : 파서)가 인덱스 대신 이름 (예 : Token [0])을 사용하는 동안 조금 더 명확 해 보이기 때문에 명명 된 Tuples를 사용했습니다.

마지막으로, 때때로, 특히 테스트를 작성하는 경우, 파일 객체 대신 토큰 화기에 문자열을 전달하는 것을 선호합니다. 나는 그것을 "독자"라고 부르며, 그것을 열고 토큰 화기가 동일한 인터페이스를 통해 액세스 할 수있는 특정 방법을 가지고 있습니다.

def open_reader(self, source):
    """
    Produces a file object from source.
    The source can be either a file object already, or a string.
    """
    if hasattr(source, 'read'):
        return source
    else:
        from io import StringIO
        return StringIO(source)

파이썬에서 새로운 것을 시작하면 일반적으로 사용할 일부 모듈이나 라이브러리를 먼저 살펴 봅니다. 이미 사용할 수있는 90%이상의 기회가 있습니다.

토큰 화제와 파서의 경우 확실히 그렇습니다. 당신은 보셨습니까? pyparsing ?

C와 같은 프로그래밍 언어를위한 토큰 화기를 구현했습니다. 내가 한 일은 토큰 생성을 두 층으로 나누는 것이 었습니다.

  • 표면 스캐너: 이것은 실제로 텍스트를 읽고 정규 표현식을 사용하여 가장 원시 토큰 (연산자, 식별자, 숫자 등)으로 만 분할; 이것은 튜플 (토 케임, 스캔 스트링, STARTPOS, ENDPOS)을 생성합니다.
  • 토큰 화기: 이것은 첫 번째 레이어에서 튜플을 소비하여 토큰 물체로 전환합니다 (튜플이 할 것이라고 생각합니다). 그 목적은 토큰 스트림의 일부 장거리 종속성, 특히 문자열 (개방 및 마감 인용문 포함) 및 댓글 (닫는 lexems를 열면 주석을 유지하고 싶었습니다!)을 싱글로 강요하는 것입니다. 토큰. 그런 다음 토큰 객체의 결과 스트림을 소비 파서로 되돌립니다.

둘 다 발전기입니다. 이 접근법의 이점은 다음과 같습니다.

  • 원시 텍스트를 읽는 것은 빠르고 깨끗한 간단한 regexps와 함께 가장 원시적 인 방식으로 만 수행됩니다.
  • 두 번째 층은 이미 원시 파서로 구현되어 문자열 리터럴과 주석 - 파서 기술 재사용을 감지합니다.
  • 복잡한 탐지로 표면 스캐너를 변형시킬 필요가 없습니다.
  • 그러나 실제 파서는 언어의 의미 론적 수준에서 토큰을 얻습니다 (다시 문자열, 주석).

이 계층화 된 접근 방식에 매우 만족합니다.

나는 우수한 사람으로 돌아갈 것입니다 파이썬의 텍스트 처리 David Mertz

이것은 늦은 대답이기 때문에 이제 공식 문서에 무언가가 있습니다. 토큰 화기 작성 이랑 re 표준 라이브러리. 이것은 PY 2.7 문서에없는 Python 3 문서의 내용입니다. 그러나 여전히 오래된 파이썬에 적용 할 수 있습니다.

여기에는 짧은 코드, Easy Setup 및 여기에서 제안한 몇 가지 답변대로 생성기 작성이 포함됩니다.

문서가 Pythonic이 아니라면 :-)

"단순히 튜플 목록을 반환하는 더 좋은 대안이 있습니까?"

토큰 화기를 구현해야했지만 튜플 목록보다 더 복잡한 접근이 필요 했으므로 각 토큰에 대한 클래스를 구현했습니다. 그런 다음 클래스 인스턴스 목록을 반환하거나 리소스를 저장하려면 반복자 인터페이스를 구현하는 것을 반환하고 구문 분석을 진행하는 동안 다음 토큰을 생성 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top