このセッションの成果(全て landing / Central 公開済み)
#40 を継承。P4 fallback=0(#32 )に向け、生成マッパーの AST 経路忠実度を root から潰すサイクルを継続。unlaxer-dsl を 3.0.7 → 3.0.8 → 3.0.9 と3回リリース し、tinyexpression を各々追従。
リリース済み(unlaxer-parser、Central公開 + master マージ)
tinyexpression(master マージ済み、master @ 733293f、unlaxer-dsl 3.0.9)
計測(if-source shadow OFF の純 AST 経路、-Dp4.disableIfSourceShadow=true 一時トグルで evalIfExpr を計測 → 計測後 revert)
P4AstEvaluatorCalculatorTest の失敗:10(3.0.5) → 6(3.0.6) → 4(3.0.7) → 2(3.0.8) → 1(3.0.9)
3.0.7 で testStringUpperAndLowerCase / testInDayTimeRange、3.0.8 で testMin / testMax、3.0.9 で testStringSlice が AST 経路で PASS。
P4BackendParityTest は if-off でも 0 fail。
if-ON baseline ゲートは全リリースで緑 (新規失敗ゼロ。既知失敗は perf: 生成パーサの指数バックトラック — 二重カッコ三項/ソース再パース経路で秒〜分単位の遅延 #38 testTernaryInSinWithDoubleParensStillWorks の1件のみ)。
🎯 残り = C のみ(最後の if-off 失敗): var 宣言 / 型推論(testTypeInference)
これは codegen バグでなく「機能」 。testTypeInference block 1:
var $name as string set if not exists 'opa' description='名前だよ!';
if($name == $remitterAccountHolderKana){1}else{0}
(ctx: $name 未設定, $remitter='opai'。期待 0)
根本原因(精査済み)
var 宣言は @mapping 無し (@declares のみ)。P4 mapper の findBestMappedToken は Expression だけを残し宣言を捨てる 。よって純 AST 経路では宣言が提供する2つが欠落:
値 $name='opa'(set if not exists)
型 as string → $name == $remitter を文字列比較 にすべき情報
型情報が無く $name == $remitter は構造的に数値寄り比較にマップされ、'opa'/'opai' を数値比較 → 誤って等価 → 1(期待 0)。
必要な作業(専用の機能開発。恐らく 3.0.10)
VariableDeclaration ルール群を AST にマップ(codegen)or 宣言トークンを別経路で抽出
context へ set-if-not-exists を適用
宣言型を比較オペランドの型解決に通す(StringComparison vs 数値 ComparisonExpr の選択)
文法: tools/tinyexpression-p4-lsp-vscode/grammar/tinyexpression-p4.ubnf の VariableDeclaration / *VariableDeclaration(41-93行)。legacy 側の実装は evaluator/javacode/VariableTypeResolver.java, TinyExpressionTokens.java, parser.javalang.VariableDeclarationParser が参考。
#32 fallback=0 のもう一つのゲート: パース性能(#38 /#20 )
if-shadow を実際に外すには、巨大ネスト if 式(不正検知 fraud formula)のパース が遅すぎる問題も要解決。P4AstEvaluatorCalculatorTest は if-ON でも ~1263s (パース時間が支配的、eval ではない)。unlaxer-parser のメモ化(packrat, unlaxer-parser#40)導入待ち。
ビルド/検証コマンド
tinyexpression フル: mvn -o verify -Dmaven.test.failure.ignore=true -Dtinyexpression.skipRailroad=true -Dgpg.skip=true -Dmaven.javadoc.skip=true -Dspotbugs.skip=true -Derrorprone.skip=true
緑判定ゲート : bash tools/ci/check-test-baseline.sh(mvn test 自体は既知失敗で BUILD FAILURE。test-baseline.txt の唯一の既知失敗=perf: 生成パーサの指数バックトラック — 二重カッコ三項/ソース再パース経路で秒〜分単位の遅延 #38 )
再生成: rm -rf target/generated-sources target/classes
unlaxer-dsl をローカル検証: revision を 3.0.10-SNAPSHOT 等にして cd unlaxer-parser && mvn -o -q install -pl .,unlaxer-common,unlaxer-dsl -DskipTests -Dgpg.skip=true ...(公開済み revision を汚さない )。tinyexpression の pom も同 SNAPSHOT に。
unlaxer-dsl 内部フルビルド検証(ubnf/tinycalc 生成+compile): mvn -o -q test-compile -pl unlaxer-dsl/ubnf-vscode,unlaxer-dsl/tinycalc-vscode ...、dsl テスト: mvn -o test -pl unlaxer-dsl ...(golden 変更時は更新 )。
golden 再生成 : mvn -o -q exec:java -pl unlaxer-dsl -Dexec.mainClass=org.unlaxer.dsl.codegen.SnapshotFixtureWriter -Dexec.args="--output-dir <dir>" -Dexec.classpathScope=test(temp に出力→diff 確認→src/test/resources/golden/ へ copy)。
if-off 計測: evalIfExpr 先頭を if (!Boolean.getBoolean("p4.disableIfSourceShadow")) { ...既存... } で包む → mvn -o test -Dtest='P4AstEvaluatorCalculatorTest#testTypeInference' -Dp4.disableIfSourceShadow=true ...。計測後 git checkout -- で revert 。
Central デプロイ: cd unlaxer-parser && mvn -B -pl .,unlaxer-common,unlaxer-dsl clean deploy(autoPublish、GPG loopback 設定済み)。不可逆な公開操作は権限ゲートあり=実行前にユーザー確認 。CHANGELOG 起票必須。
codegen 実装メモ(今回の重要箇所)
unlaxer-dsl/.../codegen/MapperRuleEmitter.java: findCapturedToken(直接子優先・bounded fallback)、findDescendantsBounded、emitPlainMappingBody/emitPlainMappingResolution(多ルール dispatch)、emitUtilities(parsersClass, mappedRuleNames)。
MapperElementUtil.java: parserClassLiteral の identifier トークンは FQN 条件分岐 (FQN→<Parsers>.<Token>Parser ラッパー、短縮名→base org.unlaxer.parser.clang.IdentifierParser)。短縮名トークン(CompileVerificationTest の TINYCALC_GRAMMAR token IDENTIFIER = IdentifierParser)はラッパー非生成なので base 必須。
MapperTypeResolver.isTransparentMappedChoice(≥2 異種 @mapping )、ASTGenerator/MapperTypeResolver の inferTypeFromElement が透過 choice を Object 推論。
運用メモ(ユーザー方針)
速度優先 : ローカル緑なら admin-merge 可。Central→repo1 同期ラグで downstream PR の CI が一時赤になるのは許容(同期後 gh run rerun)。
不可逆な公開操作(Central deploy)・issueコメント投稿は権限ゲートあり。
.flattened-pom.xml / package-lock.json はビルド生成物。コミット前に git checkout -- で戻す。scratch ログも掃除。
関連 issue / memory
#32 (fallback=0計画), #35 (workaround真っ当化/load-bearing shadow), #22 (機能ギャップ/dotメソッドリテラル受け手), #38 (perf:指数バックトラック), unlaxer-parser #40 (packrat)/#41 /#42 。前 handoff #40 。
memory: p4-issue32-stringconcat-blocker, p4-issue35-cycle-landscape(C のスコープ・3.0.7/3.0.8/3.0.9 成果・gotcha を記録), tinyexpression-ci-baseline-gate, workflow-speed-over-green-ci, p4-fallback-zero-project。
このセッションの成果(全て landing / Central 公開済み)
#40 を継承。P4 fallback=0(#32)に向け、生成マッパーの AST 経路忠実度を root から潰すサイクルを継続。unlaxer-dsl を 3.0.7 → 3.0.8 → 3.0.9 と3回リリースし、tinyexpression を各々追従。
リリース済み(unlaxer-parser、Central公開 + master マージ)
Object推論し、assoc fold operand をmapTransparentValueで実 AST ノードへ解決(string-concat / boolean-equality / slice 受け手)。findCapturedToken=直接子優先)で if 分岐・slice index のグローバル索引誤カウントを是正(load-bearing if-shadow の中核)。+ identifier トークンのラッパー参照修正(VariableRefExpr.name/ import@alias・@methodが空になる問題)。emitPlainMappingResolution)+ bounded fallback(findDescendantsBounded/CAPTURE_BOUNDARY_PARSERS=全 mapped-rule で停止)。tinyexpression(master マージ済み、master @
733293f、unlaxer-dsl 3.0.9)計測(if-source shadow OFF の純 AST 経路、
-Dp4.disableIfSourceShadow=true一時トグルでevalIfExprを計測 → 計測後 revert)🎯 残り = C のみ(最後の if-off 失敗): var 宣言 / 型推論(testTypeInference)
これは codegen バグでなく「機能」。testTypeInference block 1:
(ctx: $name 未設定, $remitter='opai'。期待 0)
根本原因(精査済み)
var 宣言は
@mapping無し(@declaresのみ)。P4 mapper のfindBestMappedTokenは Expression だけを残し宣言を捨てる。よって純 AST 経路では宣言が提供する2つが欠落:$name='opa'(set if not exists)as string→$name == $remitterを文字列比較にすべき情報型情報が無く
$name == $remitterは構造的に数値寄り比較にマップされ、'opa'/'opai' を数値比較 → 誤って等価 → 1(期待 0)。必要な作業(専用の機能開発。恐らく 3.0.10)
tools/tinyexpression-p4-lsp-vscode/grammar/tinyexpression-p4.ubnfのVariableDeclaration/*VariableDeclaration(41-93行)。legacy 側の実装はevaluator/javacode/VariableTypeResolver.java,TinyExpressionTokens.java,parser.javalang.VariableDeclarationParserが参考。#32 fallback=0 のもう一つのゲート: パース性能(#38/#20)
if-shadow を実際に外すには、巨大ネスト if 式(不正検知 fraud formula)のパースが遅すぎる問題も要解決。P4AstEvaluatorCalculatorTest は if-ON でも ~1263s(パース時間が支配的、eval ではない)。unlaxer-parser のメモ化(packrat, unlaxer-parser#40)導入待ち。
ビルド/検証コマンド
mvn -o verify -Dmaven.test.failure.ignore=true -Dtinyexpression.skipRailroad=true -Dgpg.skip=true -Dmaven.javadoc.skip=true -Dspotbugs.skip=true -Derrorprone.skip=truebash tools/ci/check-test-baseline.sh(mvn test自体は既知失敗で BUILD FAILURE。test-baseline.txtの唯一の既知失敗=perf: 生成パーサの指数バックトラック — 二重カッコ三項/ソース再パース経路で秒〜分単位の遅延 #38)rm -rf target/generated-sources target/classes3.0.10-SNAPSHOT等にしてcd unlaxer-parser && mvn -o -q install -pl .,unlaxer-common,unlaxer-dsl -DskipTests -Dgpg.skip=true ...(公開済み revision を汚さない)。tinyexpression の pom も同 SNAPSHOT に。mvn -o -q test-compile -pl unlaxer-dsl/ubnf-vscode,unlaxer-dsl/tinycalc-vscode ...、dsl テスト:mvn -o test -pl unlaxer-dsl ...(golden 変更時は更新)。mvn -o -q exec:java -pl unlaxer-dsl -Dexec.mainClass=org.unlaxer.dsl.codegen.SnapshotFixtureWriter -Dexec.args="--output-dir <dir>" -Dexec.classpathScope=test(temp に出力→diff 確認→src/test/resources/golden/へ copy)。evalIfExpr先頭をif (!Boolean.getBoolean("p4.disableIfSourceShadow")) { ...既存... }で包む →mvn -o test -Dtest='P4AstEvaluatorCalculatorTest#testTypeInference' -Dp4.disableIfSourceShadow=true ...。計測後git checkout --で revert。cd unlaxer-parser && mvn -B -pl .,unlaxer-common,unlaxer-dsl clean deploy(autoPublish、GPG loopback 設定済み)。不可逆な公開操作は権限ゲートあり=実行前にユーザー確認。CHANGELOG 起票必須。codegen 実装メモ(今回の重要箇所)
unlaxer-dsl/.../codegen/MapperRuleEmitter.java:findCapturedToken(直接子優先・bounded fallback)、findDescendantsBounded、emitPlainMappingBody/emitPlainMappingResolution(多ルール dispatch)、emitUtilities(parsersClass, mappedRuleNames)。MapperElementUtil.java:parserClassLiteralの identifier トークンは FQN 条件分岐(FQN→<Parsers>.<Token>Parserラッパー、短縮名→baseorg.unlaxer.parser.clang.IdentifierParser)。短縮名トークン(CompileVerificationTest の TINYCALC_GRAMMARtoken IDENTIFIER = IdentifierParser)はラッパー非生成なので base 必須。MapperTypeResolver.isTransparentMappedChoice(≥2 異種 @mapping)、ASTGenerator/MapperTypeResolverのinferTypeFromElementが透過 choice を Object 推論。運用メモ(ユーザー方針)
gh run rerun)。.flattened-pom.xml/package-lock.jsonはビルド生成物。コミット前にgit checkout --で戻す。scratch ログも掃除。関連 issue / memory
#32(fallback=0計画), #35(workaround真っ当化/load-bearing shadow), #22(機能ギャップ/dotメソッドリテラル受け手), #38(perf:指数バックトラック), unlaxer-parser #40(packrat)/#41/#42。前 handoff #40。
memory:
p4-issue32-stringconcat-blocker,p4-issue35-cycle-landscape(C のスコープ・3.0.7/3.0.8/3.0.9 成果・gotcha を記録),tinyexpression-ci-baseline-gate,workflow-speed-over-green-ci,p4-fallback-zero-project。