Files
hakorune/docs/development/roadmap/phases/phase-12.7/grammar-technical-spec.txt

267 lines
7.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

================================================================================
Nyash文法改革 - 技術仕様書(パーサー実装向け)
2025-09-03
================================================================================
1. トークン定義
================================================================================
【予約語Keywords】15個
- box, new, me, public, if, else, loop, break, continue
- peek, return, import, from, birth, fn
【演算子・記号Operators/Symbols
- 算術: + - * / %
- 比較: == != < > <= >=
- 論理: and or not
- 代入: =
- アクセス: . (ドット) [ ] (インデックス)
- 関数: ( ) { }
- 区切り: , ;
- 型注釈: :
- peekアーム: =>
- 親メソッド: ::
- コメント: // /* */
【リテラルLiterals
- 整数: /[0-9]+/
- 浮動小数: /[0-9]+\.[0-9]+/
- 文字列: /"([^"\\]|\\.)*"/
- 真偽値: true false
- null値: null
【識別子Identifier
- /[a-zA-Z_][a-zA-Z0-9_]*/
- 予約語と衝突しない
【空白・改行】
- 改行は文の区切り(セミコロン自動挿入規則適用)
- インデント: 意味を持たないPython風ではない
- 行継続: \ で明示的に次行へ続く
================================================================================
2. 式構文Expression Grammar
================================================================================
【優先順位(高→低)】
1. リテラル、識別子、(式)
2. 関数呼び出し: expr(args)
3. メンバアクセス: expr.member
4. インデックス: expr[index]
5. 単項演算: not expr, -expr
6. 乗除: * / %
7. 加減: + -
8. 比較: < > <= >= == !=
9. 論理積: and
10. 論理和: or
11. peek式: peek expr { ... }
【結合規則】
- 算術演算子: 左結合
- 比較演算子: 非結合a < b < c は不可)
- 論理演算子: 左結合
【式の種類】
```
Expression ::=
| Literal
| Identifier
| "me"
| Expression "." Identifier // メンバアクセス
| Expression "[" Expression "]" // インデックス
| Expression "(" ExprList? ")" // 関数呼び出し
| "new" Identifier "(" ExprList? ")" // インスタンス生成
| "fn" "(" ParamList? ")" Block // 関数Box
| PeekExpression
| BinaryOp
| UnaryOp
| "(" Expression ")"
```
【peek式】
```
PeekExpression ::=
"peek" Expression "{"
PeekArm*
"else" "=>" (Expression | Block)
"}"
PeekArm ::=
Pattern "=>" (Expression | Block)
Pattern ::=
| Literal // 現在はリテラルのみ
| Pattern "|" Pattern // 将来: 複数パターン
```
================================================================================
3. 文構文Statement Grammar
================================================================================
```
Statement ::=
| Expression // 式文
| "local" IdentList ("=" ExprList)? // 変数宣言
| Identifier "=" Expression // 代入
| "if" Expression Block ("else" (Block | Statement))?
| "loop" "(" Expression ")" Block
| "break"
| "continue"
| "return" Expression?
| BoxDeclaration
| FunctionDeclaration
| "import" StringLiteral ("as" Identifier)?
Block ::= "{" Statement* "}"
BoxDeclaration ::=
"box" Identifier ("from" IdentList)? "{"
FieldDeclaration*
MethodDeclaration*
"}"
FieldDeclaration ::=
("public")? Identifier ":" Identifier ("=" Expression)?
MethodDeclaration ::=
("public")? (Identifier | "birth") "(" ParamList? ")" Block
```
================================================================================
4. 名前解決規則
================================================================================
【スコープ】
1. グローバルスコープbox、関数定義
2. Box内スコープフィールド、メソッド
3. 関数スコープ引数、local変数
4. ブロックスコープ({}内のlocal
【シャドーイング】
- 内側のスコープが外側を隠蔽
- 同一スコープ内での再定義は不可
【meの解決】
- Box内: 現在のBoxインスタンス
- fn{}内: 関数Box自身
- それ以外: エラー
【from Parent.method()の解決】
- 現在のBoxがParentにデリゲートしているか確認
- Parent::method()も同様
================================================================================
5. 曖昧性と解決策
================================================================================
【左再帰なし】
- 全て右再帰または反復で記述
【最長一致】
- トークナイザーレベルで最長一致
- 例: ">=" は2文字演算子として認識
【バックトラック不要】
- LL(1)またはLL(2)で解析可能
- peekトークンで次の構文要素を判別
【曖昧箇所】
1. 関数呼び出し vs 変数
- 解決: "("の有無で判別
2. {} がブロックか関数Boxか
- 解決: 直前のfnキーワードで判別
3. セミコロン自動挿入
- 改行時に次が中置演算子でない場合挿入
- 例外: 行末が不完全な式の場合は挿入しない
================================================================================
6. エラー処理
================================================================================
【期待トークンエラー】
```
Expected 'token' but found 'actual'
at line X, column Y
```
【回復戦略】
1. 文レベル: 次の文開始トークンまでスキップ
2. ブロックレベル: 対応する}までスキップ
3. Box/関数レベル: 次のbox/fnまでスキップ
【行・列の追跡】
- 各トークンに位置情報を付与
- エラー時は該当箇所を表示
【エラーメッセージ例】
```
Error: Missing 'else' in peek expression
--> program.nyash:10:5
|
10 | peek value {
| ^^^^ peek expression requires 'else' branch
```
================================================================================
7. 将来拡張の余地
================================================================================
【予約済み位置】
- @ 記号: 将来の属性用
- # 記号: 将来のマクロ用
- ` 記号: 将来のテンプレート用
【拡張可能な構文】
- Pattern: 現在はリテラルのみ、将来は構造体パターン等
- 型注釈: 現在は : Type のみ、将来はジェネリクス等
【前方互換性】
- 未知の @ で始まる行は読み飛ばし
- box内の未知セクションは警告のみ
================================================================================
8. 既存実装への差分最小化
================================================================================
【tokenizer.rs への変更】
1. 予約語リストにpeek, continue, birthを追加
2. => を2文字演算子として追加
3. :: を2文字演算子として追加
【parser.rs への変更】
1. parse_when() → parse_peek() に改名
2. parse_field_declaration() を追加name: Type形式
3. parse_fn_literal() を追加fn式のため
4. continue文の処理追加
5. birthキーワードの特殊処理
【AST変更】
```rust
// 追加
enum Expr {
// ...
Peek {
scrutinee: Box<Expr>,
arms: Vec<(Pattern, BlockOrExpr)>,
else_arm: Box<BlockOrExpr>,
},
FnLiteral {
params: Vec<String>,
body: Block,
},
}
enum Stmt {
// ...
Continue,
}
```
【セマンティクス】
- peekは式として値を返す
- else必須のバリデーション追加
- returnは最内関数スコープから脱出
================================================================================