필자는 파이썬에서 컴파일러를 작성하고 있는데 필자는 PLY에서 들여 쓰기를 파싱하는 방법을 알아낼 수 없기 때문에 필기체 렉서를 만들었습니다. 또한, 내 렉서 지금과 같은 몇 가지 yield
문 사용하지만수작업으로 작성한 렉서 (lexer) 용 PLY 인터페이스를 작성하는 방법은 무엇입니까?
def scan():
...
for i in tokens:
if i[0]: yield Token(self.line, i[0] if i[0] in keywords else "ident", i[0])
elif i[1]:
if "e" in i[1]:
base, exp = i[1].split("e")
val = float(base) * 10 ** int(exp)
else: val = float(i[1])
yield Token(self.line, "float", val)
... other cases ...
을, 나는 PLY 파서는 token
방법을 필요로 실현, 그래서 나는 다음과 같다 하나 만들어 :
def token(self):
return next(self.scan())
실제 검사를 내 테스트에 따르면 scan()
을 사용하면 평균 124ms가 걸리지 만 PLY 파서를 사용하면 몇 분 후에 파싱이 시작되지 않습니다. 내 방법에 문제가있는 것으로 보입니다.
또한 이 인터페이스가 될 수 있도록 scan()
메서드의 이름을 바꾸려고했습니다. 파이썬은 다음과 같은 것을 반환합니다.
AttributeError: 'generator' object has no attribute 'type'
그래서 PLY에는 한 번에 하나의 토큰을 반환하는 메서드가 필요합니다.
메서드를 다시 작성하여 다음 반복을 scan()
으로 돌려 주지만 느리지는 않습니까?
def start(...):
self.lexer = self.scan()
def token(...):
return next(self.lexer)
면책 조항 :
그런데 들여 쓰기를 구문 분석하려는 경우에도 대부분의 렉싱에 PLY를 사용할 수 있습니다. 렉서 (lexer)를 통해 모든 공백 개행 문자를 전달하고 토큰 스트림을 후 처리하여 적절한 내제/딕트 토큰을 삽입하십시오. 이 작업을 수행 할 때 구문 분석 단계에 PLY를 사용하지 않았으므로이를 통합 할 필요가 없으므로이 질문에 대답 할 수 없습니다. 그러나 그것은 렉서를 더 쉽게 쓸 수 있도록 해줍니다. – delnan
@delnan _probably_ 작동 할 수 있지만, 또한 알아낼 수없는 것은 들여 쓰기를 처리하기 위해 하나의 규칙에 대해 여러 토큰을 반환하는 방법입니다. 나머지는 이미 코딩 할 수 있습니다. –