Implement namespace parser

This commit is contained in:
Kazuki Tsunemi 2023-03-09 17:42:38 +09:00
parent c1df62638d
commit 4017bb3c49
3 changed files with 91 additions and 1 deletions

View File

@ -392,6 +392,29 @@ const setDirection = (dir: string) => {
direction = dir;
};
/**
* Function called by parser when a namespace keyword has been found.
*
* @param id - Id of the namespace to add
* @public
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const addNamespace = function (id: string) {
// TODO: Implement here
};
/**
* Function called by parser when a namespace definition has been found.
*
* @param id - Id of the namespace to add
* @param classNames - Ids of the class to add
* @public
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const addClassesToNamespace = function (id: string, classNames: string[]) {
// TODO: Implement here
};
export default {
parseDirective,
setAccTitle,
@ -425,4 +448,6 @@ export default {
setDiagramTitle,
getDiagramTitle,
setClassLabel,
addNamespace,
addClassesToNamespace,
};

View File

@ -571,6 +571,37 @@ foo()
const str = 'classDiagram\n' + 'note "test"\n';
parser.parse(str);
});
it('should handle "namespace"', function () {
const str = `classDiagram
namespace Namespace1 { class Class1 }
namespace Namespace2 { class Class1
}
namespace Namespace3 {
class Class1 {
int : test
string : foo
test()
foo()
}
}
namespace Namespace4 {
class Class1 {
int : test
string : foo
test()
foo()
}
class Class2 {
int : test
string : foo
test()
foo()
}
}
`;
parser.parse(str);
});
});
describe('when fetching data from a classDiagram it', function () {

View File

@ -21,6 +21,8 @@
%x acc_descr_multiline
%x class
%x class-body
%x namespace
%x namespace-body
%%
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
.*direction\s+TB[^\n]* return 'direction_tb';
@ -48,9 +50,20 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
"classDiagram" return 'CLASS_DIAGRAM';
"[*]" return 'EDGE_STATE';
"class" { this.begin('class'); return 'CLASS';}
<INITIAL,namespace>"namespace" { this.begin('namespace'); return 'NAMESPACE'; }
<namespace>\s*(\r?\n)+ { this.popState(); return 'NEWLINE'; }
<namespace>\s+ /* skip whitespace */
<namespace>[{] { this.begin("namespace-body"); return 'STRUCT_START';}
<namespace-body>[}] { this.popState(); return 'STRUCT_STOP'; }
<namespace-body><<EOF>> return "EOF_IN_STRUCT";
<namespace-body>\s*(\r?\n)+ return 'NEWLINE';
<namespace-body>\s+ /* skip whitespace */
<namespace-body>"[*]" return 'EDGE_STATE';
<INITIAL,namespace-body>"class" { this.begin('class'); return 'CLASS';}
<class>\s*(\r?\n)+ { this.popState(); return 'NEWLINE'; }
<class>\s+ /* skip whitespace */
<class>[}] { this.popState(); this.popState(); return 'STRUCT_STOP';}
<class>[{] { this.begin("class-body"); return 'STRUCT_START';}
<class-body>[}] { this.popState(); return 'STRUCT_STOP'; }
<class-body><<EOF>> return "EOF_IN_STRUCT";
@ -264,6 +277,11 @@ classLabel
: SQS STR SQE { $$=$2; }
;
namespaceName
: alphaNumToken { $$=$1; }
| alphaNumToken namespaceName { $$=$1+$2; }
;
className
: alphaNumToken { $$=$1; }
| classLiteralName { $$=$1; }
@ -275,6 +293,7 @@ className
statement
: relationStatement { yy.addRelation($1); }
| relationStatement LABEL { $1.title = yy.cleanupLabel($2); yy.addRelation($1); }
| namespaceStatement
| classStatement
| methodStatement
| annotationStatement
@ -288,6 +307,21 @@ statement
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
;
namespaceStatement
: namespaceIdentifier STRUCT_START classStatements STRUCT_STOP {yy.addClassesToNamespace($1, $3);}
| namespaceIdentifier STRUCT_START NEWLINE classStatements STRUCT_STOP {yy.addClassesToNamespace($1, $4);}
;
namespaceIdentifier
: NAMESPACE namespaceName {$$=$2; yy.addNamespace($2);}
;
classStatements
: classStatement {$$=[$1]}
| classStatement NEWLINE {$$=[$1]}
| classStatement NEWLINE classStatements {$3.unshift($1); $$=$3}
;
classStatement
: classIdentifier
| classIdentifier STYLE_SEPARATOR alphaNumToken {yy.setCssClass($1, $3);}