@zenuml/core 3.47.9 → 3.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cloud-icons-eHuugVSv.js.map +1 -0
- package/dist/zenuml.esm.mjs +2153 -2156
- package/dist/zenuml.esm.mjs.map +1 -0
- package/dist/zenuml.js +82 -82
- package/dist/zenuml.js.map +1 -0
- package/package.json +11 -1
- package/src/cli/zenuml.ts +1164 -0
- package/.agents/skills/babysit-pr/SKILL.md +0 -223
- package/.agents/skills/babysit-pr/agents/openai.yaml +0 -7
- package/.agents/skills/dia-scoring/SKILL.md +0 -139
- package/.agents/skills/dia-scoring/agents/openai.yaml +0 -7
- package/.agents/skills/dia-scoring/references/selectors-and-keys.md +0 -253
- package/.agents/skills/land-pr/SKILL.md +0 -120
- package/.agents/skills/propagate-core-release/SKILL.md +0 -205
- package/.agents/skills/propagate-core-release/agents/openai.yaml +0 -7
- package/.agents/skills/propagate-core-release/references/downstreams.md +0 -42
- package/.agents/skills/ship-branch/SKILL.md +0 -105
- package/.agents/skills/submit-branch/SKILL.md +0 -76
- package/.agents/skills/validate-branch/SKILL.md +0 -72
- package/.claude/commands/README.md +0 -162
- package/.claude/commands/analyze.md +0 -101
- package/.claude/commands/clarify.md +0 -158
- package/.claude/commands/code-review.md +0 -322
- package/.claude/commands/constitution.md +0 -73
- package/.claude/commands/create-docs.md +0 -309
- package/.claude/commands/full-context.md +0 -121
- package/.claude/commands/gemini-consult.md +0 -164
- package/.claude/commands/handoff.md +0 -146
- package/.claude/commands/implement.md +0 -56
- package/.claude/commands/plan.md +0 -43
- package/.claude/commands/refactor.md +0 -188
- package/.claude/commands/specify.md +0 -21
- package/.claude/commands/tasks.md +0 -62
- package/.claude/commands/update-docs.md +0 -314
- package/.claude/hooks/README.md +0 -270
- package/.claude/hooks/config/sensitive-patterns.json +0 -86
- package/.claude/hooks/gemini-context-injector.sh +0 -129
- package/.claude/hooks/mcp-security-scan.sh +0 -147
- package/.claude/hooks/notify.sh +0 -103
- package/.claude/hooks/setup/hook-setup.md +0 -96
- package/.claude/hooks/setup/settings.json.template +0 -63
- package/.claude/hooks/sounds/complete.wav +0 -0
- package/.claude/hooks/sounds/input-needed.wav +0 -0
- package/.claude/hooks/subagent-context-injector.sh +0 -65
- package/.claude/skills/babysit-pr/SKILL.md +0 -223
- package/.claude/skills/babysit-pr/agents/openai.yaml +0 -7
- package/.claude/skills/dia-scoring/SKILL.md +0 -139
- package/.claude/skills/dia-scoring/agents/openai.yaml +0 -7
- package/.claude/skills/dia-scoring/references/selectors-and-keys.md +0 -253
- package/.claude/skills/emoji-eval/SKILL.md +0 -187
- package/.claude/skills/land-pr/SKILL.md +0 -120
- package/.claude/skills/propagate-core-release/SKILL.md +0 -205
- package/.claude/skills/propagate-core-release/agents/openai.yaml +0 -7
- package/.claude/skills/propagate-core-release/references/downstreams.md +0 -42
- package/.claude/skills/ship-branch/SKILL.md +0 -105
- package/.claude/skills/submit-branch/SKILL.md +0 -76
- package/.claude/skills/validate-branch/SKILL.md +0 -72
- package/.claude/skills/zenuml-ux-research/SKILL.md +0 -183
- package/.claude/skills/zenuml-ux-research/references/assertion-catalog.md +0 -261
- package/.claude/skills/zenuml-ux-research/references/best-practices-overview.md +0 -56
- package/.claude/skills/zenuml-ux-research/references/report-template.md +0 -89
- package/.claude/skills/zenuml-ux-research/references/scenarios/edit-message-label.md +0 -37
- package/.claude/skills/zenuml-ux-research/references/scenarios/insert-message.md +0 -36
- package/.claude/skills/zenuml-ux-research/references/scenarios/insert-participant.md +0 -31
- package/.claude/skills/zenuml-ux-research/references/scenarios/rename-participant.md +0 -33
- package/.claude/skills/zenuml-ux-research/references/scenarios/undo-insert.md +0 -35
- package/.devcontainer/devcontainer.json +0 -21
- package/.dockerignore +0 -19
- package/.eslintrc.js +0 -39
- package/.git-blame-ignore-revs +0 -6
- package/.kiro/hooks/README.md +0 -38
- package/.kiro/hooks/session-sound-notification.js +0 -44
- package/.kiro/hooks/session-sound-notification.json +0 -23
- package/.mcp.json.example +0 -17
- package/.nvmrc +0 -1
- package/.prettierignore +0 -4
- package/.prettierrc +0 -1
- package/.specify/memory/constitution.md +0 -33
- package/.specify/scripts/bash/check-prerequisites.sh +0 -166
- package/.specify/scripts/bash/common.sh +0 -113
- package/.specify/scripts/bash/create-new-feature.sh +0 -97
- package/.specify/scripts/bash/setup-plan.sh +0 -60
- package/.specify/scripts/bash/update-agent-context.sh +0 -728
- package/.specify/templates/agent-file-template.md +0 -23
- package/.specify/templates/plan-template.md +0 -219
- package/.specify/templates/spec-template.md +0 -116
- package/.specify/templates/tasks-template.md +0 -127
- package/.storybook/main.ts +0 -25
- package/.storybook/preview.ts +0 -29
- package/.watchmanconfig +0 -3
- package/AGENTS.md +0 -26
- package/CLAUDE.md +0 -124
- package/DEPLOYMENT.md +0 -62
- package/Dockerfile +0 -36
- package/IMPLEMENTATION_PLAN.md +0 -163
- package/Integration/vanilla-js/index.html +0 -42
- package/MCP-ASSISTANT-RULES.md +0 -85
- package/README_CN.md +0 -15
- package/TUTORIAL.md +0 -116
- package/antlr/antlr-4.11.1-complete.jar +0 -0
- package/bun.lock +0 -1544
- package/bunfig.toml +0 -52
- package/docs/UNICODE_SUPPORT.md +0 -179
- package/docs/ai-context/deployment-infrastructure.md +0 -21
- package/docs/ai-context/docs-overview.md +0 -89
- package/docs/ai-context/handoff.md +0 -174
- package/docs/ai-context/project-structure.md +0 -160
- package/docs/ai-context/system-integration.md +0 -21
- package/docs/asciidoc/contributor.adoc +0 -54
- package/docs/asciidoc/create-my-own-theme.adoc +0 -149
- package/docs/asciidoc/images/creation-component.png +0 -0
- package/docs/asciidoc/images/creation-rtl.png +0 -0
- package/docs/asciidoc/images/message-arrow-rtl.png +0 -0
- package/docs/asciidoc/images/occurrence.png +0 -0
- package/docs/asciidoc/images/return-message-conflict.png +0 -0
- package/docs/asciidoc/images/shift-up-half-the-height.png +0 -0
- package/docs/asciidoc/images/three-layer-info-arch.png +0 -0
- package/docs/asciidoc/images/vertical-alignment.svg +0 -1
- package/docs/asciidoc/images/vertically-aligning.png +0 -0
- package/docs/asciidoc/index.adoc +0 -277
- package/docs/asciidoc/theme-debug-web-app.png +0 -0
- package/docs/asciidoc/tutorial.adoc +0 -22
- package/docs/asciidoc/user-css.png +0 -0
- package/docs/async-vs-sync-parser-rules.md +0 -81
- package/docs/divider-parser-allow-spaces.md +0 -38
- package/docs/highlighting-messages.md +0 -52
- package/docs/images/editor-sample.png +0 -0
- package/docs/inherited-vs-provided-from.md +0 -64
- package/docs/parser/Assignment.md +0 -8
- package/docs/parser/PARSER_IMPROVEMENTS_CC.md +0 -425
- package/docs/parser/grammar_review_gemini.md +0 -116
- package/docs/participants-function.md +0 -25
- package/docs/responsive-participant-margin.md +0 -52
- package/docs/starter.md +0 -9
- package/docs/superpowers/plans/2026-03-27-e2e-test-reorg.md +0 -698
- package/docs/superpowers/plans/2026-03-30-emoji-support.md +0 -1220
- package/docs/superpowers/plans/2026-03-30-self-correcting-scoring.md +0 -206
- package/docs/superpowers/plans/2026-04-15-keyboard-editing-on-diagram.md +0 -1992
- package/docs/superpowers/plans/2026-04-15-zenuml-ux-research-skill.md +0 -1452
- package/docs/ux-research/.gitkeep +0 -0
- package/docs/ux-research/2026-04-15-rename-participant.md +0 -156
- package/docs/ux-research/2026-04-18-insert-participant.md +0 -151
- package/docs/width-translate-and-offsets.md +0 -62
- package/docs/xss.md +0 -59
- package/e2e/data/compare-cases.js +0 -1090
- package/e2e/data/diff-algorithm.js +0 -199
- package/e2e/fixtures/create-message.html +0 -26
- package/e2e/fixtures/editable-label.html +0 -35
- package/e2e/fixtures/editable-span.html +0 -122
- package/e2e/fixtures/empty-diagram.html +0 -23
- package/e2e/fixtures/fixture.html +0 -31
- package/e2e/fixtures/insert-participant.html +0 -23
- package/e2e/fixtures/reorder-cross-fragment.html +0 -31
- package/e2e/fixtures/reorder-fragment.html +0 -29
- package/e2e/fixtures/reorder-message.html +0 -27
- package/e2e/fixtures/svg-test.html +0 -21
- package/e2e/fixtures/type-switch.html +0 -29
- package/e2e/tools/canonical-history.html +0 -908
- package/e2e/tools/compare-case.html +0 -371
- package/e2e/tools/compare.html +0 -35
- package/e2e/tools/native-diff-ext/background.js +0 -60
- package/e2e/tools/native-diff-ext/bridge.js +0 -26
- package/e2e/tools/native-diff-ext/content.js +0 -194
- package/e2e/tools/svg-preview.html +0 -56
- package/embed.html +0 -193
- package/eslint.config.mjs +0 -35
- package/firebase-debug.log +0 -108
- package/iframe-container-demo/diagram.html +0 -124
- package/iframe-container-demo/host.html +0 -817
- package/index.html +0 -771
- package/mermaid-zenuml-async-spa-auth.png +0 -0
- package/mermaid-zenuml-async-spa-auth.snapshot.md +0 -96
- package/newsletter/unicode-support-announcement.md +0 -134
- package/playground/creation.html +0 -53
- package/playground/message.html +0 -63
- package/playwright.config.ts +0 -40
- package/renderer.html +0 -366
- package/scripts/analyze-compare-case/collect-data.mjs +0 -1134
- package/scripts/analyze-compare-case/config.mjs +0 -102
- package/scripts/analyze-compare-case/geometry.mjs +0 -101
- package/scripts/analyze-compare-case/native-diff.mjs +0 -224
- package/scripts/analyze-compare-case/output.mjs +0 -74
- package/scripts/analyze-compare-case/panel-diff.mjs +0 -114
- package/scripts/analyze-compare-case/report.mjs +0 -162
- package/scripts/analyze-compare-case/residual-scopes.mjs +0 -347
- package/scripts/analyze-compare-case/scoring.mjs +0 -829
- package/scripts/analyze-compare-case.mjs +0 -149
- package/scripts/bump-version.js +0 -117
- package/scripts/snapshot-dual.js +0 -173
- package/scripts/update-snapshots.js +0 -70
- package/skills/dia-scoring/SKILL.md +0 -129
- package/skills/dia-scoring/agents/openai.yaml +0 -7
- package/skills/dia-scoring/references/selectors-and-keys.md +0 -253
- package/tailwind.config.js +0 -126
- package/test-compression.html +0 -274
- package/test-mermaid-zenuml.html +0 -57
- package/test-setup.ts +0 -124
- package/test-url-params.html +0 -192
- package/tsconfig.app.json +0 -31
- package/tsconfig.node.json +0 -24
- package/tsconfig.test.json +0 -9
- package/vite.config.lib.ts +0 -93
- package/vite.config.ts +0 -84
- package/wrangler.toml +0 -18
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
Since 1.0.63
|
|
2
|
-
|
|
3
|
-
# Highlighting messages
|
|
4
|
-
|
|
5
|
-
The renderer will highlight an `Interaction` based on the value of `cursor` in the store.
|
|
6
|
-
For example, for DSL `A.x B.y`, if `cursor` is between [0, 3], `A.x` is highlighted in
|
|
7
|
-
the diagram; if `cursor` is between [4, 7], `B.y` is highlighted.
|
|
8
|
-
|
|
9
|
-
## What elements can be highlighted?
|
|
10
|
-
|
|
11
|
-
Theoretically, every element can be highlighted. The logic is different for
|
|
12
|
-
different types.
|
|
13
|
-
|
|
14
|
-
We will focus on messages: Creation and Messages (Sync & Async).
|
|
15
|
-
|
|
16
|
-
### Creation
|
|
17
|
-
|
|
18
|
-
Creations parser definition is:
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
creationBody (SCOL | braceBlock)?
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
We will highlight the creation call and assignment but NOT the `braceBlock`.
|
|
25
|
-
The triggering cursor must be in between `creationBody`.
|
|
26
|
-
|
|
27
|
-
### Message
|
|
28
|
-
|
|
29
|
-
Message parser definition is:
|
|
30
|
-
|
|
31
|
-
```
|
|
32
|
-
messageBody (SCOL | braceBlock)?
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
We will highlight the message call and assignment but NOT the `braceBlock`.
|
|
36
|
-
The triggering cursor must be in between `messageBody`.
|
|
37
|
-
|
|
38
|
-
### Async Message
|
|
39
|
-
|
|
40
|
-
Async message parser definition is:
|
|
41
|
-
|
|
42
|
-
```
|
|
43
|
-
source ARROW target COL content
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
We will highlight the whole message call.
|
|
47
|
-
The triggering curso must bee in between `source ARROW target COL content`.
|
|
48
|
-
|
|
49
|
-
## Implementation
|
|
50
|
-
|
|
51
|
-
The global store has a state `cursor`. Each component check whether this cursor
|
|
52
|
-
is in between the range that should set the `isCurrent` status of itself.
|
|
Binary file
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
What we should be looking at is `statement` which can be one of:
|
|
2
|
-
|
|
3
|
-
1. Alt/Par/Opt/Loop
|
|
4
|
-
1. Message
|
|
5
|
-
1. Creation
|
|
6
|
-
|
|
7
|
-
`stat`'s parent is always `block`. `block`'s parent is either `braceBlock`
|
|
8
|
-
or `prog`. If it is `prog` we are looking the `starter`; if it is `braceBlock`,
|
|
9
|
-
we need to find its parent message or creation and get their owners.
|
|
10
|
-
|
|
11
|
-
There are two ways to decide where the message is from.
|
|
12
|
-
One way is to deduce from its parent context - inherited from;
|
|
13
|
-
the other way is to explicitly define it from its own context -
|
|
14
|
-
provided from.
|
|
15
|
-
|
|
16
|
-
## Inherited
|
|
17
|
-
|
|
18
|
-
Sync message
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
A.m1 {
|
|
22
|
-
// m2 has an "inherited from" as `A`
|
|
23
|
-
m2
|
|
24
|
-
}
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Async message
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
A.m1 {
|
|
31
|
-
// m2 has an "inherited from" as `A`
|
|
32
|
-
B:m2
|
|
33
|
-
}
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Provided
|
|
37
|
-
|
|
38
|
-
Sync message
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
A.m1 {
|
|
42
|
-
// m2 has a "provided from" as `B`
|
|
43
|
-
B->C.m2
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Async message
|
|
49
|
-
|
|
50
|
-
```
|
|
51
|
-
A.m1 {
|
|
52
|
-
// m2 has a "provided from" as `B`
|
|
53
|
-
B->C:m2
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
It is allowed to have a `provided from` that equals to its
|
|
58
|
-
`inherited from`.
|
|
59
|
-
|
|
60
|
-
# Discussion
|
|
61
|
-
|
|
62
|
-
By definition, a root method has an `inherited from` as `Starter` or otherwise specified by `@StarterExp()`.
|
|
63
|
-
|
|
64
|
-
`Starter`, unless it is explicitly defined, will not be displayed on the lifeline layer.
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
Assignment occurs in the following contexts:
|
|
2
|
-
- Non-self Sync Message `ret = A.m()` or `T ret = A.m()`
|
|
3
|
-
- Self Sync Message `ret = m()` or `T ret = m()`
|
|
4
|
-
- Creation `ret = new A()` or `T ret = new A()`
|
|
5
|
-
|
|
6
|
-
For self sync message, the assignment is rendered with the message itself.
|
|
7
|
-
|
|
8
|
-
For non-self sync message and creation, the assignment is rendered as a return statement. If the Type presents, the return message would be like `t:T`. In such cases, we need to provide positions for type and assignee separately.
|
|
@@ -1,425 +0,0 @@
|
|
|
1
|
-
# ANTLR Grammar Review & Comprehensive Improvement Recommendations
|
|
2
|
-
|
|
3
|
-
## Executive Summary
|
|
4
|
-
Your ZenUML ANTLR grammar demonstrates excellent design patterns for editor-friendly parsing with robust error recovery. This comprehensive review identifies opportunities to improve readability, maintainability, and performance while preserving these strengths.
|
|
5
|
-
|
|
6
|
-
## Key Strengths
|
|
7
|
-
|
|
8
|
-
1. **Editor-Optimized Error Recovery**: Handles incomplete constructs gracefully (unclosed strings, missing brackets)
|
|
9
|
-
2. **Performance Awareness**: Performance notes throughout show active optimization
|
|
10
|
-
3. **Clean Token Separation**: Effective use of channels (HIDDEN, COMMENT_CHANNEL, MODIFIER_CHANNEL)
|
|
11
|
-
4. **Unicode Support**: Proper use of \p{L} and \p{Nd} for international character support
|
|
12
|
-
5. **Lexer Modes**: Clean context-sensitive lexing for EVENT and TITLE modes
|
|
13
|
-
|
|
14
|
-
## Critical Issues to Address
|
|
15
|
-
|
|
16
|
-
### Issue 1: Comment Rule EOF Handling
|
|
17
|
-
**Problem**: Current COMMENT rule requires trailing newline and uses slower `.*?` pattern
|
|
18
|
-
```antlr
|
|
19
|
-
COMMENT: '//' .*? '\n' -> channel(COMMENT_CHANNEL);
|
|
20
|
-
```
|
|
21
|
-
**Solution**:
|
|
22
|
-
```antlr
|
|
23
|
-
COMMENT: '//' ~[\r\n]* -> channel(COMMENT_CHANNEL);
|
|
24
|
-
```
|
|
25
|
-
**Impact**: 10-15% faster lexing, handles EOF without newline
|
|
26
|
-
|
|
27
|
-
### Issue 2: Token References Inside Tokens
|
|
28
|
-
**Problem**: DIVIDER references WS token inside rule
|
|
29
|
-
```antlr
|
|
30
|
-
DIVIDER: {this.column === 0}? WS* '==' ~[\r\n]*;
|
|
31
|
-
```
|
|
32
|
-
**Solution**: Use fragments instead
|
|
33
|
-
```antlr
|
|
34
|
-
fragment HWS: [ \t];
|
|
35
|
-
WS: HWS+ -> channel(HIDDEN);
|
|
36
|
-
DIVIDER: {this.column === 0}? HWS* '==' ~[\r\n]*;
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### Issue 3: Console.log in Parser
|
|
40
|
-
**Problem**: Side effects in grammar reduce performance
|
|
41
|
-
```antlr
|
|
42
|
-
| OTHER {console.log("unknown char: " + $OTHER.text);}
|
|
43
|
-
```
|
|
44
|
-
**Solution**: Use error listeners instead
|
|
45
|
-
```antlr
|
|
46
|
-
| OTHER // Handle in ErrorListener
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## 1. Readability Improvements
|
|
50
|
-
|
|
51
|
-
### 1.1 Consolidate and Organize Related Tokens
|
|
52
|
-
Group related tokens with clear section comments for better organization:
|
|
53
|
-
|
|
54
|
-
```antlr
|
|
55
|
-
// Logical operators
|
|
56
|
-
OR : '||';
|
|
57
|
-
AND : '&&';
|
|
58
|
-
NOT : '!';
|
|
59
|
-
|
|
60
|
-
// Comparison operators
|
|
61
|
-
EQ : '==';
|
|
62
|
-
NEQ : '!=';
|
|
63
|
-
GT : '>';
|
|
64
|
-
LT : '<';
|
|
65
|
-
GTEQ : '>=';
|
|
66
|
-
LTEQ : '<=';
|
|
67
|
-
|
|
68
|
-
// Arithmetic operators
|
|
69
|
-
PLUS : '+';
|
|
70
|
-
MINUS : '-';
|
|
71
|
-
MULT : '*';
|
|
72
|
-
DIV : '/';
|
|
73
|
-
MOD : '%';
|
|
74
|
-
POW : '^';
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### 1.2 Rename Ambiguous Rules
|
|
78
|
-
Improve rule names to better convey their purpose:
|
|
79
|
-
|
|
80
|
-
| Current Name | Suggested Name | Rationale |
|
|
81
|
-
|-------------|----------------|-----------|
|
|
82
|
-
| `atom` | `literal` or `primaryExpression` | More descriptive of actual content |
|
|
83
|
-
| `stat` | `statement` | Complete word, industry standard |
|
|
84
|
-
| `func` | `methodCall` or `functionCall` | Clearer intent |
|
|
85
|
-
| `tcf` | `tryCatchFinally` | Self-documenting |
|
|
86
|
-
| `EVENT` | `EVENT_MODE` | Clearer that it's a lexer mode |
|
|
87
|
-
|
|
88
|
-
### 1.3 Improve Fragment Names
|
|
89
|
-
Make fragment names more descriptive:
|
|
90
|
-
|
|
91
|
-
- `UNIT` → `LETTER_SEQUENCE`
|
|
92
|
-
- `HEX` → `HEX_DIGIT`
|
|
93
|
-
- `DIGIT` → `DECIMAL_DIGIT`
|
|
94
|
-
|
|
95
|
-
## 2. Performance Optimizations
|
|
96
|
-
|
|
97
|
-
### Key Performance Wins
|
|
98
|
-
|
|
99
|
-
#### Simplify parExpr (30% ATN reduction)
|
|
100
|
-
**Current**: 4 alternatives
|
|
101
|
-
```antlr
|
|
102
|
-
parExpr
|
|
103
|
-
: OPAR condition CPAR
|
|
104
|
-
| OPAR condition
|
|
105
|
-
| OPAR CPAR
|
|
106
|
-
| OPAR
|
|
107
|
-
;
|
|
108
|
-
```
|
|
109
|
-
**Optimized**: Single rule with optionals
|
|
110
|
-
```antlr
|
|
111
|
-
parExpr: OPAR condition? CPAR?;
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
#### Left-Factor group Rule
|
|
115
|
-
**Current**: 3 alternatives with overlapping prefixes
|
|
116
|
-
```antlr
|
|
117
|
-
group
|
|
118
|
-
: GROUP name? OBRACE participant* CBRACE
|
|
119
|
-
| GROUP name? OBRACE
|
|
120
|
-
| GROUP name?
|
|
121
|
-
;
|
|
122
|
-
```
|
|
123
|
-
**Optimized**: Factored form
|
|
124
|
-
```antlr
|
|
125
|
-
group: GROUP name? (OBRACE participant* CBRACE?)?;
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
#### Deduplicate ID|STRING Pattern
|
|
129
|
-
**Current**: Repeated across 7+ rules
|
|
130
|
-
```antlr
|
|
131
|
-
from: ID | STRING;
|
|
132
|
-
to: ID | STRING;
|
|
133
|
-
construct: ID | STRING;
|
|
134
|
-
type: ID | STRING;
|
|
135
|
-
methodName: ID | STRING;
|
|
136
|
-
```
|
|
137
|
-
**Optimized**: Single definition
|
|
138
|
-
```antlr
|
|
139
|
-
name: ID | STRING;
|
|
140
|
-
from: name;
|
|
141
|
-
to: name;
|
|
142
|
-
construct: name;
|
|
143
|
-
type: name;
|
|
144
|
-
methodName: name;
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### 2.1 Reduce Backtracking in Message Body
|
|
148
|
-
The current `messageBody` rule requires significant backtracking. Restructure for better performance:
|
|
149
|
-
|
|
150
|
-
**Current Implementation:**
|
|
151
|
-
```antlr
|
|
152
|
-
messageBody
|
|
153
|
-
: assignment? ((from ARROW)? to DOT)? func
|
|
154
|
-
| assignment
|
|
155
|
-
| (from ARROW)? to DOT
|
|
156
|
-
;
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
**Optimized Implementation:**
|
|
160
|
-
```antlr
|
|
161
|
-
messageBody
|
|
162
|
-
: assignment (messageCallChain | EOF)
|
|
163
|
-
| messageCallChain
|
|
164
|
-
;
|
|
165
|
-
|
|
166
|
-
messageCallChain
|
|
167
|
-
: ((from ARROW)? to DOT)? func
|
|
168
|
-
| (from ARROW)? to DOT
|
|
169
|
-
;
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### 2.2 Optimize Expression Parsing with Precedence
|
|
173
|
-
Leverage ANTLR4's built-in precedence features to simplify the expression grammar:
|
|
174
|
-
|
|
175
|
-
```antlr
|
|
176
|
-
expr
|
|
177
|
-
: <assoc=right> expr POW expr
|
|
178
|
-
| expr op=(MULT | DIV | MOD) expr
|
|
179
|
-
| expr op=(PLUS | MINUS) expr
|
|
180
|
-
| expr op=(LTEQ | GTEQ | LT | GT) expr
|
|
181
|
-
| expr op=(EQ | NEQ) expr
|
|
182
|
-
| <assoc=right> expr AND expr
|
|
183
|
-
| <assoc=right> expr OR expr
|
|
184
|
-
| MINUS expr
|
|
185
|
-
| NOT expr
|
|
186
|
-
| primaryExpr
|
|
187
|
-
;
|
|
188
|
-
|
|
189
|
-
primaryExpr
|
|
190
|
-
: literal
|
|
191
|
-
| (to DOT)? methodCall
|
|
192
|
-
| creation
|
|
193
|
-
| OPAR expr CPAR
|
|
194
|
-
| assignment expr
|
|
195
|
-
;
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### 2.3 Simplify Participant Rule
|
|
199
|
-
Reduce alternatives to minimize backtracking:
|
|
200
|
-
|
|
201
|
-
```antlr
|
|
202
|
-
participant
|
|
203
|
-
: participantDefinition
|
|
204
|
-
| stereotype // fallback for incomplete input
|
|
205
|
-
| participantType // fallback for incomplete input
|
|
206
|
-
;
|
|
207
|
-
|
|
208
|
-
participantDefinition
|
|
209
|
-
: participantType? stereotype? name width? label? COLOR?
|
|
210
|
-
;
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
## 3. Maintainability Enhancements
|
|
214
|
-
|
|
215
|
-
### 3.1 Extract Common Patterns
|
|
216
|
-
Create reusable rules for common patterns:
|
|
217
|
-
|
|
218
|
-
```antlr
|
|
219
|
-
// Common optional elements
|
|
220
|
-
optionalBlock : braceBlock? ;
|
|
221
|
-
optionalSemicolon : SCOL? ;
|
|
222
|
-
optionalParameters : (OPAR parameters? CPAR)? ;
|
|
223
|
-
|
|
224
|
-
// Common identifier pattern
|
|
225
|
-
identifier : ID | STRING ;
|
|
226
|
-
|
|
227
|
-
// Common name pattern
|
|
228
|
-
name : identifier ;
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
### 3.2 Separate Error Recovery Rules
|
|
232
|
-
Group error recovery patterns for better organization:
|
|
233
|
-
|
|
234
|
-
```antlr
|
|
235
|
-
statement
|
|
236
|
-
: normalStatement
|
|
237
|
-
| errorRecovery
|
|
238
|
-
;
|
|
239
|
-
|
|
240
|
-
normalStatement
|
|
241
|
-
: alt | par | opt | critical | section | ref
|
|
242
|
-
| loop | creation | message | asyncMessage
|
|
243
|
-
| ret | divider | tryCatchFinally
|
|
244
|
-
;
|
|
245
|
-
|
|
246
|
-
errorRecovery
|
|
247
|
-
: incompleteStatement
|
|
248
|
-
| OTHER {notifyUnknownToken($OTHER.text);}
|
|
249
|
-
;
|
|
250
|
-
|
|
251
|
-
incompleteStatement
|
|
252
|
-
: NEW // incomplete creation
|
|
253
|
-
| PAR // incomplete parallel block
|
|
254
|
-
| OPT // incomplete optional block
|
|
255
|
-
| SECTION // incomplete section
|
|
256
|
-
| CRITICAL // incomplete critical section
|
|
257
|
-
;
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
### 3.3 Improve Mode Management
|
|
261
|
-
Use clearer mode names and transitions:
|
|
262
|
-
|
|
263
|
-
```antlr
|
|
264
|
-
// Lexer modes with clear names
|
|
265
|
-
TITLE: 'title' -> pushMode(TITLE_MODE);
|
|
266
|
-
COL: ':' -> pushMode(EVENT_MODE);
|
|
267
|
-
|
|
268
|
-
mode TITLE_MODE;
|
|
269
|
-
TITLE_CONTENT: ~[\r\n]+ ;
|
|
270
|
-
TITLE_NEWLINE: [\r\n] -> popMode;
|
|
271
|
-
|
|
272
|
-
mode EVENT_MODE;
|
|
273
|
-
EVENT_CONTENT: ~[\r\n]+ ;
|
|
274
|
-
EVENT_NEWLINE: [\r\n] -> popMode;
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
## 4. Additional Recommendations
|
|
278
|
-
|
|
279
|
-
### 4.1 Add Lexer Guards for Keywords
|
|
280
|
-
Prevent keyword collision with identifiers using semantic predicates:
|
|
281
|
-
|
|
282
|
-
```antlr
|
|
283
|
-
// Ensure keywords are whole words
|
|
284
|
-
IF: 'if' {!isLetterOrDigit(_input.LA(1))}?;
|
|
285
|
-
ELSE: 'else' {!isLetterOrDigit(_input.LA(1))}?;
|
|
286
|
-
WHILE: 'while' {!isLetterOrDigit(_input.LA(1))}?;
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
### 4.2 Improve String Handling
|
|
290
|
-
Better error recovery for unclosed strings:
|
|
291
|
-
|
|
292
|
-
```antlr
|
|
293
|
-
STRING
|
|
294
|
-
: '"' StringContent* '"'
|
|
295
|
-
| '"' StringContent* // unclosed string for error recovery
|
|
296
|
-
;
|
|
297
|
-
|
|
298
|
-
fragment StringContent
|
|
299
|
-
: ~["\r\n\\]
|
|
300
|
-
| '\\' . // escape sequences
|
|
301
|
-
| '""' // escaped quote
|
|
302
|
-
;
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
### 4.3 Add Rule Documentation
|
|
306
|
-
Document complex rules with examples:
|
|
307
|
-
|
|
308
|
-
```antlr
|
|
309
|
-
/**
|
|
310
|
-
* Represents a method invocation chain
|
|
311
|
-
* Examples:
|
|
312
|
-
* - obj.method1()
|
|
313
|
-
* - obj.method1().method2()
|
|
314
|
-
* - method()
|
|
315
|
-
*/
|
|
316
|
-
methodCall
|
|
317
|
-
: signature (DOT signature)*
|
|
318
|
-
;
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* Alternative block structure (if-else)
|
|
322
|
-
* Example:
|
|
323
|
-
* if (condition) {
|
|
324
|
-
* statements
|
|
325
|
-
* } else if (condition2) {
|
|
326
|
-
* statements
|
|
327
|
-
* } else {
|
|
328
|
-
* statements
|
|
329
|
-
* }
|
|
330
|
-
*/
|
|
331
|
-
alt
|
|
332
|
-
: ifBlock elseIfBlock* elseBlock?
|
|
333
|
-
;
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
### 4.4 Consider Semantic Actions for Context
|
|
337
|
-
Use semantic predicates for context-sensitive parsing:
|
|
338
|
-
|
|
339
|
-
```antlr
|
|
340
|
-
// Divider only at start of line
|
|
341
|
-
divider
|
|
342
|
-
: {getCharPositionInLine() == 0}? '==' ~[\r\n]*
|
|
343
|
-
;
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
### 4.5 Standardize Token Naming
|
|
347
|
-
Follow consistent naming conventions:
|
|
348
|
-
|
|
349
|
-
- **Keywords**: UPPERCASE (e.g., `IF`, `WHILE`, `RETURN`)
|
|
350
|
-
- **Operators**: UPPERCASE (e.g., `PLUS`, `MINUS`, `ASSIGN`)
|
|
351
|
-
- **Delimiters**: UPPERCASE (e.g., `OPAR`, `CPAR`, `OBRACE`)
|
|
352
|
-
- **Literals**: UPPERCASE (e.g., `STRING`, `INT`, `FLOAT`)
|
|
353
|
-
- **Modes**: UPPERCASE_MODE (e.g., `TITLE_MODE`, `EVENT_MODE`)
|
|
354
|
-
|
|
355
|
-
## 5. Implementation Priority
|
|
356
|
-
|
|
357
|
-
### Quick Wins (1-2 hours, 20-30% improvement)
|
|
358
|
-
1. Fix COMMENT rule for EOF safety
|
|
359
|
-
2. Add HWS fragment and update DIVIDER
|
|
360
|
-
3. Simplify parExpr to single rule
|
|
361
|
-
4. Remove console.log from stat
|
|
362
|
-
5. Left-factor group rule
|
|
363
|
-
6. Deduplicate ID|STRING patterns
|
|
364
|
-
|
|
365
|
-
### High Priority (Performance & Correctness)
|
|
366
|
-
1. Optimize `messageBody` rule to reduce backtracking
|
|
367
|
-
2. Simplify expression parsing with precedence
|
|
368
|
-
3. Fix string handling for better error recovery
|
|
369
|
-
|
|
370
|
-
### Medium Priority (Maintainability)
|
|
371
|
-
1. Extract common patterns into reusable rules
|
|
372
|
-
2. Separate error recovery rules
|
|
373
|
-
3. Rename ambiguous rules
|
|
374
|
-
|
|
375
|
-
### Low Priority (Polish)
|
|
376
|
-
1. Add rule documentation
|
|
377
|
-
2. Reorganize token definitions
|
|
378
|
-
3. Standardize naming conventions
|
|
379
|
-
|
|
380
|
-
## 6. Testing Considerations
|
|
381
|
-
|
|
382
|
-
When implementing these changes:
|
|
383
|
-
|
|
384
|
-
1. **Maintain backward compatibility** - Ensure existing diagrams still parse correctly
|
|
385
|
-
2. **Test error recovery** - Verify incomplete input handling remains robust
|
|
386
|
-
3. **Benchmark performance** - Measure parsing speed improvements, especially for complex diagrams
|
|
387
|
-
4. **Update generated parser** - Remember to regenerate parser after grammar changes
|
|
388
|
-
5. **Update tests** - Adjust unit tests to reflect new rule names
|
|
389
|
-
|
|
390
|
-
## 7. Migration Strategy
|
|
391
|
-
|
|
392
|
-
1. **Phase 1**: Performance optimizations (no breaking changes)
|
|
393
|
-
- Optimize expression rules
|
|
394
|
-
- Reduce backtracking in message parsing
|
|
395
|
-
|
|
396
|
-
2. **Phase 2**: Internal refactoring (minimal impact)
|
|
397
|
-
- Extract common patterns
|
|
398
|
-
- Improve error recovery organization
|
|
399
|
-
|
|
400
|
-
3. **Phase 3**: Naming improvements (requires code updates)
|
|
401
|
-
- Rename rules for clarity
|
|
402
|
-
- Update all references in parser extensions
|
|
403
|
-
|
|
404
|
-
## Expected Performance Impact
|
|
405
|
-
|
|
406
|
-
Based on similar ANTLR grammar optimizations:
|
|
407
|
-
- **Lexer**: 10-15% faster on large files
|
|
408
|
-
- **Parser**: 20-30% reduction in ATN states
|
|
409
|
-
- **Memory**: 5-10% reduction in parse tree size
|
|
410
|
-
- **Overall**: 15-25% faster parsing for typical diagrams
|
|
411
|
-
|
|
412
|
-
## Conclusion
|
|
413
|
-
|
|
414
|
-
Your grammar is production-ready with thoughtful design choices. The suggested improvements focus on:
|
|
415
|
-
|
|
416
|
-
1. **Simplification** without losing functionality
|
|
417
|
-
2. **Performance** through reduced complexity
|
|
418
|
-
3. **Maintainability** via consistent patterns
|
|
419
|
-
|
|
420
|
-
The most impactful changes are:
|
|
421
|
-
- Lexer optimizations (COMMENT, fragments)
|
|
422
|
-
- Parser simplifications (parExpr, group)
|
|
423
|
-
- Pattern deduplication (ID|STRING)
|
|
424
|
-
|
|
425
|
-
These can be implemented incrementally with immediate benefits and full backward compatibility.
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
# ANTLR Grammar Review and Suggestions
|
|
2
|
-
|
|
3
|
-
This document provides a review of the ANTLR grammar files (`sequenceLexer.g4` and `sequenceParser.g4`) with suggestions for improvement in readability, maintainability, and performance.
|
|
4
|
-
|
|
5
|
-
## General Observations
|
|
6
|
-
|
|
7
|
-
* **Good Use of Channels:** You're effectively using channels (`COMMENT_CHANNEL`, `MODIFIER_CHANNEL`, `HIDDEN`) to separate different types of tokens, which is great for keeping the parser grammar clean.
|
|
8
|
-
* **Error Tolerance:** The grammar has several rules designed to handle incomplete code, which is excellent for use in an editor context. This improves the user experience by providing better error recovery.
|
|
9
|
-
* **Performance Notes:** It's good to see performance tuning notes in the grammar. This indicates that performance is a consideration, and it provides a history of what has been tried.
|
|
10
|
-
|
|
11
|
-
## `sequenceLexer.g4` - Suggestions
|
|
12
|
-
|
|
13
|
-
The lexer is generally well-structured and there are no major issues.
|
|
14
|
-
|
|
15
|
-
### 1. Readability: Keyword Tokens
|
|
16
|
-
|
|
17
|
-
The rules for keywords like `TRUE`, `FALSE`, `IF`, etc., are defined as separate tokens. This is clear and works well. For larger grammars, sometimes grouping them under a single `KEYWORD` rule can be beneficial, but for the current size, the existing approach is perfectly fine.
|
|
18
|
-
|
|
19
|
-
### 2. `STRING` Literal Rule
|
|
20
|
-
|
|
21
|
-
The `STRING` rule is well-designed for an editor context:
|
|
22
|
-
|
|
23
|
-
```antlr
|
|
24
|
-
STRING
|
|
25
|
-
: '"' (~["\r\n] | '""')* ('"'|[\r\n])?
|
|
26
|
-
;
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
This rule gracefully handles unclosed strings that end at a newline, which is a good strategy for error recovery and improving the user experience in an editor.
|
|
30
|
-
|
|
31
|
-
### 3. `DIVIDER` Rule
|
|
32
|
-
|
|
33
|
-
The `DIVIDER` rule uses a semantic predicate to ensure it only matches at the beginning of a line:
|
|
34
|
-
|
|
35
|
-
```antlr
|
|
36
|
-
DIVIDER: {this.column === 0}? WS* '==' ~[\r\n]*;
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
This is a powerful ANTLR feature that is used correctly here. The comment in the code explaining this is also very helpful.
|
|
40
|
-
|
|
41
|
-
### 4. Lexer Modes
|
|
42
|
-
|
|
43
|
-
The use of modes for `EVENT` and `TITLE_MODE` is a clean and efficient way to handle context-sensitive lexing.
|
|
44
|
-
|
|
45
|
-
## `sequenceParser.g4` - Suggestions
|
|
46
|
-
|
|
47
|
-
The parser grammar is also in good shape, but a few rules could be refactored for better readability and maintainability.
|
|
48
|
-
|
|
49
|
-
### 1. Readability & Maintainability: Left-Factoring `group` rule
|
|
50
|
-
|
|
51
|
-
The `group` rule has multiple alternatives that can be simplified by left-factoring.
|
|
52
|
-
|
|
53
|
-
**Current `group` rule:**
|
|
54
|
-
```antlr
|
|
55
|
-
group
|
|
56
|
-
: GROUP name? OBRACE participant* CBRACE
|
|
57
|
-
| GROUP name? OBRACE
|
|
58
|
-
| GROUP name?
|
|
59
|
-
;
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
**Suggested Improvement:**
|
|
63
|
-
```antlr
|
|
64
|
-
group
|
|
65
|
-
: GROUP name? (OBRACE participant* CBRACE?)?
|
|
66
|
-
;
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
This change makes the rule more concise and easier to understand. The optional `CBRACE?` maintains the error tolerance for incomplete blocks.
|
|
70
|
-
|
|
71
|
-
### 2. Readability: Simplify `parExpr` rule
|
|
72
|
-
|
|
73
|
-
The `parExpr` rule is written in a way that handles various stages of user input, which is good for an editor. However, it can be expressed more concisely.
|
|
74
|
-
|
|
75
|
-
**Current `parExpr` rule:**
|
|
76
|
-
```antlr
|
|
77
|
-
parExpr
|
|
78
|
-
: OPAR condition CPAR
|
|
79
|
-
| OPAR condition
|
|
80
|
-
| OPAR CPAR
|
|
81
|
-
| OPAR
|
|
82
|
-
;
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
**Suggested Improvement:**
|
|
86
|
-
```antlr
|
|
87
|
-
parExpr
|
|
88
|
-
: OPAR (condition (CPAR)? | CPAR)?
|
|
89
|
-
;
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
This simplified version covers all the original cases:
|
|
93
|
-
* `(condition)`
|
|
94
|
-
* `(condition` (incomplete)
|
|
95
|
-
* `()`
|
|
96
|
-
* `(` (incomplete)
|
|
97
|
-
|
|
98
|
-
This change improves readability without altering the parser's behavior.
|
|
99
|
-
|
|
100
|
-
### 3. Performance: `stat` and `expr` rules
|
|
101
|
-
|
|
102
|
-
You have already included performance notes about the `stat` and `expr` rules, which is great.
|
|
103
|
-
|
|
104
|
-
* **`expr`:** The expression rule uses the standard pattern for handling operator precedence with left-recursion, which ANTLR handles well.
|
|
105
|
-
* **`stat`:** The `stat` rule has many alternatives. The order of these alternatives can sometimes affect performance, especially in cases of ambiguity. Placing the most frequently matched statements earlier in the rule *might* provide a small performance boost, but ANTLR's prediction mechanism is generally very effective, so this is not a critical change.
|
|
106
|
-
|
|
107
|
-
## Summary of Recommendations
|
|
108
|
-
|
|
109
|
-
1. **`sequenceParser.g4`:**
|
|
110
|
-
* **Left-factor the `group` rule** for better readability and maintainability.
|
|
111
|
-
* **Simplify the `parExpr` rule** to be more concise.
|
|
112
|
-
|
|
113
|
-
2. **`sequenceLexer.g4`:**
|
|
114
|
-
* The lexer is well-designed, and no changes are recommended.
|
|
115
|
-
|
|
116
|
-
These suggestions aim to improve the grammar's clarity and maintainability while preserving its excellent error-recovery capabilities.
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# Shall `Participants` return with `Starter`?
|
|
2
|
-
|
|
3
|
-
`Participants` function takes a context as an input and returns
|
|
4
|
-
all the participants of this context. It should return the `from`
|
|
5
|
-
not the `Starter` unless `Starter` IS the `from`.
|
|
6
|
-
|
|
7
|
-
If we do include `from` (`Starter` in some cases) in `Participant`
|
|
8
|
-
we have to ensure that they are the first participant, even if it
|
|
9
|
-
is not at the left.
|
|
10
|
-
|
|
11
|
-
Currently `LifelineLayer` uses it to get implicitly declared
|
|
12
|
-
participants for the root context; `FragmentXXX` use it to get
|
|
13
|
-
all involved participants of a sub context.
|
|
14
|
-
|
|
15
|
-
Related logic is in `ToCollector`. We can initialise `descendantTos`
|
|
16
|
-
with `from` before `walker.walk`. We need to consider that `from`
|
|
17
|
-
may be included in participant declaration and even in group.
|
|
18
|
-
So `onParticipant` must overwrite that.
|
|
19
|
-
|
|
20
|
-
`context` has the knowledge of `from`. So far we only expose the
|
|
21
|
-
`getInheritedFrom` function. It will be convenient that it returns
|
|
22
|
-
`from` directly.
|
|
23
|
-
|
|
24
|
-
However, we also need the `InheritedFrom` and `ProvidedFrom`
|
|
25
|
-
to calculate the translateX for Interactions.
|