PEP 269 – Python용 Pgen 모듈
- Author:
- Jonathan Riehl <jriehl at spaceship.com>
- Status:
- Deferred
- Type:
- Standards Track
- Created:
- 24-Aug-2001
- Python-Version:
- 2.2
- Post-History:
Table of Contents
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
parser 모듈이 Python 파서를 노출하는 것과 마찬가지로, 이 PEP는 Python 파서를 만드는 데 사용되는 파서 제너레이터인 pgen을 Python의 모듈로 노출할 것을 제안합니다.
근거
Python의 역사 전반에 걸쳐 Python 컴파일러 제작에 관한 논의가 수없이 있었습니다 [1]. 그 결과 여러 Python 파서 구현이 나왔으며, 그중 가장 대표적인 것은 현재 Python 표준 라이브러리에서 제공하는 parser 모듈 [2] 과 Jeremy Hylton의 compiler 모듈 [3] 입니다. 그러나 여러 언어 변경이 제안되었음에도 [4] [5], Python 문법에 대한 실험은 Python을 빌드하는 데 실제로 사용되는 파서 제너레이터에 대한 Python 바인딩의 이점을 누리지 못했습니다.
Fred Drake Jr.의 파서 래퍼와 유사하지만 pgen 라이브러리를 대상으로 하는 Python 래퍼를 제공함으로써, 다음과 같은 주장을 할 수 있습니다:
- 문법 변경의 참조 구현을 더 쉽게 개발할 수 있을 것입니다. 현재는 문법 변경의 참조 구현을 만들려면 개발자가 명령줄에서
pgen도구를 사용해야 합니다. 그 결과로 얻은 파서 자료 구조는 사용자 정의 CPython 구현과 인터페이스할 수 있도록 다시 작업하거나, C 확장 모듈로 감싸야 합니다. - 문법 변경의 참조 구현을 더 쉽게 배포할 수 있을 것입니다. 파서 제너레이터를 Python에서 사용할 수 있게 되므로, 그 결과로 생성된 파서 역시 Python에서 접근할 수 있게 될 것입니다. 따라서 참조 구현은 기존 CPython 배포의 커스텀 버전을 사용하거나 컴파일 가능한 확장 모듈로 제공하는 대신, 순수 Python 코드로 제공될 수 있어야 합니다.
- 문법 변경의 참조 구현을 더 많은 사람과 더 쉽게 논의할 수 있을 것입니다. 이는 어느 정도 두 번째 주장에서 자연스럽게 도출되는데, 파이썬 사용자 커뮤니티가 CPython 개발자 커뮤니티보다 클 가능성이 높기 때문입니다.
- 추가되는 모듈은 완전한 기능을 갖춘 LL(1) 파서 제너레이터가 될 것이므로, Python에서 소규모 언어를 개발하는 일이 더욱 수월해질 것입니다.
명세
제안하는 모듈의 이름은 pgen입니다. pgen 모듈은 다음 함수들을 포함합니다:
parseGrammarFile (fileName) -> AST
parseGrammarFile() 함수는 fileName이 가리키는 파일을 읽어 AST 객체를 생성합니다. AST 노드에는 파서 제너레이터 메타 문법의 비단말(nonterminal) 숫자 값이 담깁니다. 출력되는 AST는 parser 모듈이 제공하는 AST 확장 클래스의 인스턴스입니다. 입력 파일에 문법 오류가 있으면 SyntaxError 예외가 발생합니다.
parseGrammarString (text) -> AST
parseGrammarString() 함수는 parseGrammarFile()의 의미를 따르지만, 파일 이름 대신 문법 텍스트를 문자열로 입력받습니다.
buildParser (grammarAst) -> DFA
buildParser() 함수는 AST 객체를 입력으로 받아 DFA(결정적 유한 오토마톤) 자료 구조를 반환합니다. DFA 자료 구조는 parser 모듈에서 AST 구조를 제공하는 것과 마찬가지로 C 확장 클래스가 될 것입니다. 입력된 AST가 pgen 메타 문법에 정의된 비단말 코드를 따르지 않으면, buildParser()는 ValueError 예외를 발생시킵니다.
parseFile (fileName, dfa, start) -> AST
parseFile() 함수는 본질적으로 PyParser_ParseFile() C API 함수의 래퍼가 될 것입니다. 래퍼 코드는 DFA C 확장 클래스와 파일 이름을 받을 것입니다. token 모듈의 어휘 값과 DFA에 포함된 비단말 값을 따르는 AST 인스턴스가 출력될 것입니다.
parseString (text, dfa, start) -> AST
parseString() 함수는 parseFile() 함수와 비슷한 방식으로 동작하지만, 파싱할 텍스트를 인자로 받을 것입니다. parseFile()이 PyParser_ParseFile() C API 함수를 감싸는 것과 마찬가지로, parseString()은 PyParser_ParseString() 함수를 감쌀 것입니다.
symbolToStringMap (dfa) -> dict
symbolToStringMap() 함수는 DFA 인스턴스를 받아, DFA의 비단말에 대한 숫자 값을 해당 DFA의 원래 문법 명세에 나타난 비단말의 문자열 이름으로 매핑하는 딕셔너리 객체를 반환할 것입니다.
stringToSymbolMap (dfa) -> dict
stringToSymbolMap() 함수는 입력 DFA의 비단말 이름을 그에 대응하는 숫자 값으로 매핑하는 딕셔너리를 출력합니다.
매핑 생성 함수와 파싱 함수가 DFA 확장 클래스의 메서드로도 제공된다면 가산점이 주어질 것입니다.
구현 계획
이 개선을 달성하기 위해 교묘한 계획이 마련되었습니다:
pgen함수의 이름을 CPython 명명 표준에 맞게 변경합니다. 이 작업에는Include하위 디렉터리에 헤더 파일 몇 개를 추가하는 일이 포함될 수 있습니다.- Makefile.pre.in에 있는
pgenC 모듈을 별도의pgen요소에서 Python C 라이브러리로 옮깁니다. - AST 확장 클래스가 자신이 이해하지 못할 수도 있는 AST 타입이 존재한다는 것을 인식하도록
parser모듈에 필요한 변경을 가합니다. AST 확장 클래스를 대략 살펴보면, 이 클래스는 트리가 스위트인지 표현식인지를 추적하고 있음을 알 수 있습니다.
Modules디렉터리에 C 모듈을 하나 더 작성합니다. 이 C 확장 모듈은 DFA 확장 클래스와 앞 절에서 설명한 함수들을 구현할 것입니다.- 새 모듈을 빌드 과정에 추가합니다. 그야말로 흑마법입니다.
제약 사항
이 제안에 따르더라도, Python 3000을 설계하려는 사람들은 여전히 Python의 어휘 규칙에 제약을 받습니다. Python 렉서를 추가, 삭제 또는 수정하는 것은 이 PEP의 범위를 벗어납니다.
참조 구현
현재 제공되는 참조 구현은 없습니다. 한때 http://sourceforge.net/tracker/index.php?func=detail&aid=599331&group_id=5470&atid=305470 에서 패치가 제공되었지만, 그 패치는 더 이상 유지 관리되지 않습니다.
참고 문헌
Copyright
This document has been placed in the public domain.