You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The LL(k) parser (`NGrammar.parse`) produces a tree of `ParseTree.Leaf` and `ParseTree.Node` values.
6
+
7
+
### ParseTree.Leaf (tokens)
8
+
Created by `LexerDfas.lex` for each token. Fields:
9
+
-`text: String` — the matched source text (empty `""` for synthetic EOF)
10
+
-`ruleName: String` — the lexer rule name from the grammar (e.g., `"ID"`, `"INT"`, `"LBRACE"`); for string literals, the quoted form (e.g., `"'val'"`); for EOF, `"EOF"`
11
+
-`tipe: U32` — unique token type ID from `PredictiveTable.nameMap`
12
+
-`isHidden: B` — `T` for whitespace/comment tokens (skipped by `LexerDfas.tokens` when `skipHidden = T`)
13
+
-`posOpt: Option[Position]` — source position
14
+
15
+
`Leaf` also extends `Token`, so `num` is an alias for `tipe`, and `toLeaf` returns `this`.
16
+
17
+
### ParseTree.Node (grammar rules)
18
+
Created by `NGrammar.parse` for non-terminal rules. Fields:
19
+
-`children: ISZ[ParseTree]` — child nodes (Leaf or Node)
20
+
-`ruleName: String` — the grammar rule name (e.g., `"file"`, `"exp3"`, `"infixSuffix"`)
21
+
-`tipe: U32` — the rule's unique ID from `PredictiveTable.nameMap` (same namespace as token types)
22
+
-`posOpt: Option[Position]` — computed from first/last child positions
23
+
24
+
### Synthetic Rules (isSynthetic)
25
+
Grammar normalization (`Grammar.normalize`) converts `*`, `+`, `?` into synthetic recursive rules named `baseName$N` (e.g., `exp3$0`, `program$1`). These have `isSynthetic = T` in the `NRule`.
26
+
27
+
**Key behavior**: When `NRule.isSynthetic = T`, the parser **does not wrap** the children in a `ParseTree.Node`. Instead, children are inlined flat into the parent. This means:
28
+
-`rule*` / `rule+` / `rule?` do NOT produce their own nodes in the parse tree
29
+
- Their matched children appear directly as children of the enclosing non-synthetic rule
30
+
- For example, `exp3: exp2 infixSuffix*` produces a single `exp3` Node whose children are `[exp2_node, infixSuffix_node, infixSuffix_node, ...]`
31
+
32
+
### Two NRule Kinds
33
+
-`NRule.Elements` — a sequence of elements (single production). If non-synthetic, wraps children in `ParseTree.Node(trees, name, num)`.
34
+
-`NRule.Alts` — a choice among alternatives (multi-production). If non-synthetic, wraps the chosen alternative's result in `ParseTree.Node(trees, name, num)`. If synthetic, delegates directly to the chosen alternative without wrapping.
35
+
36
+
### Name/Type ID Mapping
37
+
`PredictiveTable.nameMap: HashSMap[String, U32]` maps both token names and rule names to unique `U32` IDs. `reverseNameMap` provides the inverse. String literal tokens use quoted keys like `"'val'"`. The same `U32` value appears in both `ParseTree.tipe` and `NRule.num`.
0 commit comments