Added class suppoort to the grammar

This commit is contained in:
Knut Sveidqvist
2025-05-09 13:47:45 +02:00
parent 4f8f929340
commit 680d65114c
4 changed files with 269 additions and 25 deletions

View File

@@ -9,19 +9,25 @@
grammar Treemap
// Interface declarations for data types
interface Item {}
interface Section extends Item {
interface Item {
name: string
classSelector?: string // For ::: class
}
interface Section extends Item {
}
interface Leaf extends Item {
name: string
value: number
}
interface ClassDefStatement {
className: string
styleText: string // Optional style text
}
entry TreemapDoc:
TREEMAP_KEYWORD
(TreemapRows+=TreemapRow)*;
terminal CLASS_DEF: /classDef\s+([a-zA-Z_][a-zA-Z0-9_]+)(?:\s+([^;\r\n]*))?(?:;)?/;
terminal STYLE_SEPARATOR: ':::';
terminal SEPARATOR: ':';
terminal COMMA: ',';
@@ -30,24 +36,28 @@ hidden terminal ML_COMMENT: /\%\%[^\n]*/;
hidden terminal NL: /\r?\n/;
TreemapRow:
indent=INDENTATION? item=Item;
indent=INDENTATION? (item=Item | ClassDef);
// Class definition statement handled by the value converter
ClassDef returns string:
CLASS_DEF;
Item returns Item:
Leaf | Section;
// Use a special rule order to handle the parsing precedence
Section returns Section:
name=STRING;
name=STRING (STYLE_SEPARATOR classSelector=ID)?;
Leaf returns Leaf:
name=STRING INDENTATION? (SEPARATOR | COMMA) INDENTATION? value=MyNumber;
name=STRING INDENTATION? (SEPARATOR | COMMA) INDENTATION? value=MyNumber (STYLE_SEPARATOR classSelector=ID)?;
// This should be processed before whitespace is ignored
terminal INDENTATION: /[ \t]{1,}/; // One or more spaces/tabs for indentation
// Keywords with fixed text patterns
terminal TREEMAP_KEYWORD: 'treemap';
terminal ID: /[a-zA-Z_][a-zA-Z0-9_]*/;
// Define as a terminal rule
terminal NUMBER: /[0-9_\.\,]+/;

View File

@@ -1,6 +1,9 @@
import type { CstNode, GrammarAST, ValueType } from 'langium';
import { AbstractMermaidValueConverter } from '../common/index.js';
// Regular expression to extract className and styleText from a classDef terminal
const classDefRegex = /classDef\s+([A-Z_a-z]\w+)(?:\s+([^\n\r;]*))?;?/;
export class TreemapValueConverter extends AbstractMermaidValueConverter {
protected runCustomConverter(
rule: GrammarAST.AbstractRule,
@@ -8,20 +11,33 @@ export class TreemapValueConverter extends AbstractMermaidValueConverter {
_cstNode: CstNode
): ValueType | undefined {
if (rule.name === 'NUMBER') {
// console.debug('NUMBER', input);
// Convert to a number by removing any commas and converting to float
return parseFloat(input.replace(/,/g, ''));
} else if (rule.name === 'SEPARATOR') {
// console.debug('SEPARATOR', input);
// Remove quotes
return input.substring(1, input.length - 1);
} else if (rule.name === 'STRING') {
// console.debug('STRING', input);
// Remove quotes
return input.substring(1, input.length - 1);
} else if (rule.name === 'INDENTATION') {
// console.debug('INDENTATION', input);
return input.length;
} else if (rule.name === 'ClassDef') {
// Handle both CLASS_DEF terminal and ClassDef rule
if (typeof input !== 'string') {
// If we're dealing with an already processed object, return it as is
return input;
}
// Extract className and styleText from classDef statement
const match = classDefRegex.exec(input);
if (match) {
// Use any type to avoid type issues
return {
$type: 'ClassDefStatement',
className: match[1],
styleText: match[2] || undefined,
} as any;
}
}
return undefined;
}