18.2.1.2 px4_generate_messages.py 스크립트의 렉시컬 분석(Lexical Analysis) 및 의존성 트리(Dependency Tree) 빌드
CMake 빌드 시스템이 트리거(Trigger) 조건을 만족하여 px4_generate_messages.py 스크립트를 호출하면, 이 파이썬 스크립트는 텍스트 덩어리에 불과한 .msg 파일을 읽어 들여 C++ 코드를 만기 위한 본격적인 구문 분석(Parsing) 단계에 돌입한다.
이 과정은 마치 프로그래밍 언어의 컴파일러가 소스 코드를 제일 먼저 렉서(Lexer)에 통과시키는 것과 완벽히 동일한 메커니즘을 따른다.
1. 렉시컬 분석 (Lexical Analysis) 및 구문 검증
파이썬 스크립트는 정규 표현식(Regular Expression)을 동원하여 .msg 파일의 각 라인을 토큰(Token) 단위로 쪼개는 렉시컬 분석을 수행한다.
- 필드 식별: 라인을 읽어 들여 띄어쓰기를 기준으로 분리하고, 앞부분은
Type(데이터 타입), 뒷부분은Name(변수명)으로 인식한다.
- 예:
uint64 timestamp\rightarrow 타입:uint64, 변수명:timestamp
- 엄격한 타입 검증 (Type Validation): 로드된 데이터 타입이 PX4 생태계에서 공식적으로 허용하는 원시 타입(Primitive Type:
uint8,int32,float32,bool등) 목록에 존재하는지 대조한다. 만약 개발자가 실수로 C 표준 타입인int나long을 적어 넣었다면, 이 단계에서 가차 없이 파싱 에러(Parsing Error)를 발생시키고 빌드를 중단(Abort)시킨다. - 상수 및 배열 인식:
=기호가 있으면 일반 변수가 아닌 Enum 상수(Constant)로 분류하며,[N]기호가 붙어있으면 정적 배열(Static Array) 객체로 메모리에 레이아웃 될 수 있도록 별도의 플래그(Flag)를 마킹한다.
이렇게 분석된 정보들은 파이썬 내부 머신 안에서 하나의 딕셔너리(Dictionary) 혹은 객체 리스트 형태의 추상 구문 트리(AST, Abstract Syntax Tree) 데이터로 차곡차곡 쌓이게 된다.
2. 의존성 트리(Dependency Tree)의 구축
단일 .msg 파일 내에 원시 타입만 들어 있다면 분석은 여기서 종료되겠지만, 실제 항공 소프트웨어의 메시지 구조는 훨씬 더 복잡하다. 하나의 메시지 안에 다른 메시지가 포함되는 복합 구조체(Nested Struct) 형태를 띠는 경우가 빈번하다.
- 예시:
trajectory_setpoint.msg토픽이 내부에vehicle_attitude_setpoint.msg타입을 필드로 가지는 경우.
px4_generate_messages.py 스크립트는 알 수 없는 복합 타입을 마주치면 즉시 의존성 탐색 모드로 전환한다.
- 이 타입이 같은
msg/디렉토리 내에 존재하는 다른 토픽(.msg)인지 검색한다. - 의존성이 확인되면 해당 자식(Child)
.msg파일 역시 재귀적으로 파싱(Recursive Parsing)하여 정보를 긁어모은다. - 이 과정을 바탕으로 메시지들 간의 의존성 방향 그래프(Directed Acyclic Graph) 를 메모리상에 빌드한다.
3. 의존성 트리가 필요한 이유
이 의존성 트리는 차후 C++ 헤더 파일을 찍어낼 때 핵심적인 역할을 수행한다.
만약 A 파일이 B 파일을 포어(Include)해야 하는데 전처리기 지시문(#include <uORB/topics/B.h>)을 누락하거나, 엉뚱한 순서로 선언하게 되면 C++ 컴파일러는 “알 수 없는 타입” 에러를 내뱉는다. 파이썬 스크립트가 미리 구축해 놓은 이 견고한 의존성 트리는, C++ 컴파일러가 절대 헤매지 않도록 #include 문의 순서와 위치를 정확하게 제어하는 길잡이 노릇을 하게 된다.
이렇게 구문 분석과 의존성 검증이 모두 끝나 무결성이 입증된 “메모리 상의 추상 객체(AST)“들은 이제 실제 코드로 탈바꿈하기 위해 마지막 단계인 Jinja2 템플릿 엔진으로 넘겨지게 된다.