Adding common parser for headerMode

This commit is contained in:
Knut Sveidqvist
2025-09-22 14:15:16 +02:00
parent 38428114ee
commit c98da4d022
5 changed files with 39 additions and 16 deletions

View File

@@ -52,7 +52,7 @@
"postinstall": "pnpm antlr:generate",
"checkCircle": "npx madge --circular ./src",
"antlr:sequence:clean": "rimraf src/diagrams/sequence/parser/antlr/generated",
"antlr:sequence": "pnpm run antlr:sequence:clean && antlr4ng -Dlanguage=TypeScript -Xexact-output-dir -o src/diagrams/sequence/parser/antlr/generated src/diagrams/sequence/parser/antlr/SequenceLexer.g4 src/diagrams/sequence/parser/antlr/SequenceParser.g4",
"antlr:sequence": "pnpm run antlr:sequence:clean && antlr4ng -Dlanguage=TypeScript -Xexact-output-dir -lib src/diagrams/common/parser/antlr -o src/diagrams/sequence/parser/antlr/generated src/diagrams/sequence/parser/antlr/SequenceLexer.g4 src/diagrams/sequence/parser/antlr/SequenceParser.g4",
"antlr:class:clean": "rimraf src/diagrams/class/parser/antlr/generated",
"antlr:class": "pnpm run antlr:class:clean && antlr4ng -Dlanguage=TypeScript -Xexact-output-dir -o src/diagrams/class/parser/antlr/generated src/diagrams/class/parser/antlr/ClassLexer.g4 src/diagrams/class/parser/antlr/ClassParser.g4",
"antlr:flowchart:clean": "rimraf src/diagrams/flowchart/parser/antlr/generated",

View File

@@ -3,7 +3,8 @@
// Note that JS doesn't support the "\A" anchor, which means we can't use
// multiline mode.
// Relevant YAML spec: https://yaml.org/spec/1.2.2/#914-explicit-documents
export const frontMatterRegex = /^\uFEFF?[\t ]*-{3}[\t ]*\r?\n([\S\s]*?)\r?\n-{3}[\t ]*(?:\r?\n|$)/;
export const frontMatterRegex =
/^\uFEFF?[\t ]*-{3}[\t ]*\r?\n([\S\s]*?)\r?\n {0,2}-{3}[\t ]*(?:\r?\n|$)/;
export const directiveRegex =
/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi;

View File

@@ -0,0 +1,25 @@
lexer grammar HeaderCommon;
@members {
// headerMode is true until the diagram header keyword is seen
protected headerMode = true;
// Helper to disable header mode from delegator lexers on diagram start
protected disableHeaderMode(): void { this.headerMode = false; }
}
// Header directives: only before the diagram header keyword has been seen
// Accept optional leading spaces/tabs on the line before the directive
HEADER_DIRECTIVE: { this.headerMode }? [ \t]* '%%{' .*? '}%%';
// YAML front matter (allowed only before the diagram header)
// Use a dedicated mode to consume until the closing '---' line
FRONTMATTER: { this.headerMode }? [ \t]* '---' [ \t]* ('\r'? '\n') -> pushMode(YAML_MODE);
mode YAML_MODE;
YAML_END: [ \t]* '---' [ \t]* ('\r'? '\n') -> popMode, skip;
YAML_CONTENT: . -> skip;
// Comments (skip) - simple, broad handling; rely on longest-match to keep HEADER_DIRECTIVE intact
HASH_COMMENT: '#' ~[\r\n]* -> skip;
PERCENT_COMMENT: '%%' ~[\r\n]* -> skip;

View File

@@ -1,27 +1,17 @@
lexer grammar SequenceLexer;
import HeaderCommon;
tokens { AS }
@members {
// headerMode is true until the diagram header (sequenceDiagram) is seen
private headerMode = true;
}
// Header directives: handle %%{ ... }%% only before the diagram header
// Accept optional leading spaces/tabs on the line before the directive
HEADER_DIRECTIVE: { this.headerMode }? [ \t]* '%%{' .*? '}%%';
// Comments (skip) - avoid consuming '%%{' which starts a directive
HASH_COMMENT: '#' ~[\r\n]* -> skip;
PERCENT_COMMENT1: '%%' ~['{'] ~[\r\n]* -> skip;
PERCENT_COMMENT2: ~[}] '%%' ~[\r\n]* -> skip;
// Whitespace and newline
// YAML front matter (allowed before the diagram header)
FRONTMATTER: { this.headerMode }? [ \t]* '---' [ \t]* ('\r'? '\n') .*? ('\r'? '\n') [ \t]* '---' [ \t]* ('\r'? '\n');
NEWLINE: ('\r'? '\n')+;
WS: [ \t]+ -> skip;
// Top-level comments (also defined in HeaderCommon, duplicated here to ensure availability post-header)
HASH_COMMENT_TOP: '#' ~[\r\n]* -> skip;
PERCENT_COMMENT_TOP: '%%' ~[\r\n]* -> skip;
// Punctuation and simple symbols
COMMA: ',';