Prism을 활용한 Ruby 파싱 소개

An Introduction to Ruby Parsing with Prism

작성자
HackerNews
발행일
2026년 01월 07일

핵심 요약

  • 1 Prism은 Ruby 파싱의 표준화를 목표로 하는 새로운 파서로, 기존 Ruby 구현체 및 도구들의 파서 파편화 문제를 해결합니다.
  • 2 Prism은 렉싱과 파싱 기능을 제공하여 Ruby 코드 분석 및 변환 도구(트랜스파일러, 코드 리팩토링 도구 등) 개발을 용이하게 합니다.
  • 3 본문은 Emoruby 트랜스파일러와 `Struct`를 `Data` 클래스로 변환하는 리팩토링 도구 예시를 통해 Prism의 실제 적용 방법을 상세히 설명합니다.

도입

Prism은 Ruby 개발 환경에 새로운 변화를 가져올 차세대 Ruby 파서입니다. 기존 파서 대비 더 빠르고, 안정적이며, 강력한 기능을 제공하는 Prism은 컴파일러의 기본 개념에 익숙하지 않은 개발자들에게도 Ruby 코드 분석의 새로운 지평을 열어줍니다. 본 글은 Prism의 핵심 기능과 Ruby 개발자로서 우리의 작업 방식에 어떤 영향을 미치는지 심층적으로 다루며, 이를 통해 첫 번째 트랜스파일러를 직접 구축하는 여정을 안내합니다.

프로그래밍 언어를 해석하는 과정은 일반적으로 세 단계로 이루어집니다.

  • 토큰화 (Lexing): 입력 텍스트를 의미 있는 토큰 목록으로 분해합니다.

  • 파싱 (Parsing): 토큰을 분석하여 프로그램 구조를 이해하고, 이를 추상 구문 트리(AST)와 같은 데이터 표현으로 변환합니다.

  • 평가 (Evaluating): 파싱된 입력을 실행하여 결과를 생성합니다.

Prism의 유용성

기존 Ruby 파서인 parse.y는 CRuby에 특화되어 JRuby, TruffleRuby와 같은 다른 Ruby 구현체들이 자체 파서를 개발해야 했습니다. 이로 인해 RuboCop, 코드 편집기 등 Ruby 분석 도구들이 최신 Ruby 문법을 따라가지 못하거나 호환성 문제가 발생했습니다. Prism은 이러한 문제를 해결하기 위해 모든 Ruby 도구 및 구현체의 사실상 표준 파서가 되었으며, 현재 CRuby, JRuby, TruffleRuby, Rails, RuboCop 등에서 활발히 사용되고 있습니다.

첫 번째 트랜스파일러 구축: Emoruby 변환기

Prism의 렉싱 기능을 활용하여 Ruby 코드를 Emoruby로 변환하는 트랜스파일러를 구축하는 과정을 소개합니다.

  • Prism.lex 메서드를 사용하여 입력 코드를 토큰화합니다.

  • Emoruby의 변환 파일을 참조하여 Ruby 토큰을 해당 이모지 대체제로 매핑합니다.

  • Prism::Token 인스턴스의 위치 정보를 활용하여 들여쓰기 및 공백을 정확하게 처리하여 원본 코드의 가독성을 유지합니다.

Prism 파싱 활용: Struct를 Data 클래스로 리팩토링

Ruby 3.2의 Data 클래스를 활용하여 기존 Struct를 리팩토링하는 도구를 개발합니다.

  • Prism::Visitor 클래스를 사용하여 AST 노드를 순회하며 Struct.new 호출을 식별합니다.

  • CallNode 타입을 필터링하여 Struct.new 호출을 찾아냅니다.

  • Struct 인수를 수집하고, Data.define으로 대체할 코드를 생성합니다.

  • 수정 사항은 시작 위치의 오름차순으로 적용하며, 멀티바이트 문자 처리를 위해 byteslice를 사용합니다.

뮤테이션 검사:

Data 객체는 불변성을 가지므로, 내부 상태를 변경하는 StructData로 변환할 수 없습니다. 이를 위해 중첩된 Visitor를 사용하여 Struct 본문에 뮤테이션(예: 인스턴스 변수 쓰기, 속성 쓰기)이 있는지 검사합니다.

  • “write” 작업을 수행하는 노드를 식별하여 뮤테이션을 감지합니다.

  • 상수, 지역 변수, 전역 변수 쓰기는 Struct의 내부 상태 변경으로 간주하지 않습니다.

결론

Prism은 Ruby 도구들을 더욱 빠르고, 이식 가능하며, 일관성 있게 만듦으로써 Ruby 생태계에 이미 큰 변화를 가져왔습니다. 그러나 Prism의 진정한 영향력은 개발자들이 이를 활용하여 구축할 혁신적인 프로젝트들에서 발현될 것입니다. Ruby-to-JS 트랜스파일러, 파일 및 줄 번호 기반의 테스트 러너, 심지어 코드를 픽셀 아트로 변환하는 도구에 이르기까지, 파서가 더 이상 병목 지점이 아닌 시대가 도래했습니다. 이제 개발자들의 상상력이 Ruby의 미래를 주도할 것입니다.

댓글 0

로그인이 필요합니다

댓글을 작성하거나 대화에 참여하려면 로그인이 필요합니다.

로그인 하러 가기

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!