# Step 2: Abaqus Scoped Syntax Parser ## 읽어야 할 파일 - `/AGENTS.md` - `/docs/PRD.md` - `/docs/ARCHITECTURE.md` - `/docs/ADR.md` - `/docs/superpowers/specs/2026-07-29-abaqus-assembly-reference-design.md` - `/docs/superpowers/plans/2026-07-29-fesa-phase-1.md` - `/include/fesa/core/source_location.hpp` - `/include/fesa/core/diagnostic.hpp` ## 작업 Abaqus keyword를 해석하지 않고 scope가 보존된 syntax tree로 읽는 parser를 만든다. ```cpp struct DeckRecord final { std::string keyword; std::map> parameters; std::vector> data; SourceLocation source; }; struct ParsedPart final { std::string name; std::vector records; SourceLocation source; }; struct ParsedInstance final { std::string name; std::string part_name; std::vector> transform_data; SourceLocation source; }; struct ParsedAssembly final { std::string name; std::vector instances; std::vector records; SourceLocation source; }; struct ParsedDeck final { std::vector global_records; std::vector parts; std::optional assembly; }; [[nodiscard]] ParseDeckResult parse_deck(const std::filesystem::path&); ``` - flat fixture와 단일 Part/Assembly/Instance fixture를 먼저 만든다. - case-insensitive keyword, comment, blank line, comma field, UTF-8, source line, scope 종료 오류를 테스트한다. - 이 step은 syntax만 파싱하며 active Part를 선택하지 않는다. ## Acceptance Criteria ```powershell cmake --build --preset windows-debug ctest --preset windows-debug -R "AbaqusParser|ScopedDeck" --output-on-failure ctest --preset windows-debug --output-on-failure ``` ## 검증 절차 1. parser test를 작성하고 실패를 확인한다. 2. `io/abaqus`에 lexer/parser만 최소 구현한다. 3. source location과 scope tree를 assertion한다. 4. 전체 테스트 후 index를 갱신한다. ## 금지사항 - Domain을 생성하지 마라. 이유: 다음 semantic normalization step의 책임이다. - unknown keyword를 일반적으로 무시하지 마라. 이유: 명시적 입력 계약을 훼손한다. - Instance 변환을 적용하지 마라. 이유: Phase 1에서 거부할 syntax 정보로 보존한다.