blog.stackframe.dev

블로그 개발 삽질기 2 - reStructuredText 파서 구현

  1. 블로그 개발 삽질기 0 - 발단
  2. 블로그 개발 삽질기 1 - 설계
  3. 블로그 개발 삽질기 2 - reStructuredText 파서 구현
  4. 블로그 개발 삽질기 3 - 템플릿 구현
  5. 블로그 개발 삽질기 4 - Service Worker
  6. 블로그 개발 삽질기 5 - 파서 리팩토링

설계 때 선정한 reStructuredText를 사용하기 위해서 파서가 필요했다. reStructuredText는 공식적으로 docutils라는 Python으로 작성된 프로그램을 사용하여 HTML로 변환이 가능하다. 하지만 PHP에서 Python을 실행하는건 exec()을 써야하고 영 내 마음에 들지 않는다. 거기다 기본으로 들어있는 rst2html5 명령어를 실행해보면 빈 파일을 넣어도 0.9초가 걸렸다. 웹에서 0.9초면 심각한 딜레이다. 결국 내가 직접 PHP로 파서를 구현하기로 했다.

사실 나는 컴파일러 과목을 배운 적이 없다. 지금까지 파서를 만들어 본 건 Websocket 서버를 위해 C++로 HTTP 헤더와 JSON을 파싱하고 다시 만들어내는 것 정도만 해봤고 그것마저 제너레이터 같은걸 쓴게 아니라 단순히 한글자 한글자 읽어들이면서 처리한 것 뿐이다. 이번에도 잉여스러우면서 바퀴를 재발명해 보겠다는 고집이 나를 고생시키게 되었다.

설계가 끝나고 가장 우선순위가 높다고 판단되는 파서를 맨 먼저 만들기 시작했는데, 이 파서를 구현하면서 정말 많은 시행착오를 겪었다. 이렇게 하면 되겠지 하면서 짜고 보니 이 문법과 저 문법을 구분하지 못하거나 여러 요소가 중첩으로 발생하면 꼬이고 들여쓰기 블럭을 이상하게 처리하는 등 처음부터 잘못된 방향으로 만들어서 싹 다 지우고 다시 만든게 4번이나 되었다. 그나마 초반이라서 넘처흐르는 열정과 이전에 작성했던 코드를 일부분 가져오는 것으로 금방 진행했던 곳까지 다시 만들 수 있었다. 그 결과, 지금은 이미지도 넣을 수 있다. 이렇게 기본 이론도 모르면서 맨땅에 헤딩하며 어찌저찌 굴러가는걸 만들었다는게 지금 봐도 신기할 따름이다.

내 서버에서 rst2html5를 실행한 결과 0.916s가 나왔다.

그래도 이 노력이 헛된 것만은 아니었는지 속도는 꽤나 빠르게 나온다. 한번에 16개의 문서를 파싱해도 0.1초 언저리로 나오는걸 보면 상당히 괜찮은 성능이라 생각된다. 물론 아직 미완성인 부분이 좀 있긴 하지만 말이다.

서버와 같은 네트워크에서 4개의 reStructuredText가 존재하는 페이지를 로드한 결과

현재 아직 구현되지 않았고 어떻게 구현해야 할 지 머리아픈 부분이 바로 테이블이다. 셀을 나누는 | 가 정확한 위치에 있어야되고 각 셀 안의 내용은 또 Body element로 파싱되어야 한다. 가장 큰 문제는 한글과 알파벳이 폰트 크기도 차이나고 UTF-8에서 각각 3byte, 1byte 로도 차이난다. 그래서 한글을 쓴다면 테이블이 깨질 가능성이 크고 파싱을 할 때도 아주 거슬린다. 이 문제는 그냥 테이블을 쓰지않는걸로 해버리는게 가장 속편할지도 모르겠다.

댓글