Skip to content

Commit

Permalink
added parser
Browse files Browse the repository at this point in the history
  • Loading branch information
Austin Fulbright authored and Austin Fulbright committed Jul 25, 2024
1 parent 1a95d48 commit d0eadeb
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 11 deletions.
4 changes: 2 additions & 2 deletions packages/mermaid/src/diagrams/git/gitGraphDiagram.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// @ts-ignore: JISON doesn't support types
import gitGraphParser from './parser/gitGraph.jison';
import { parser } from './gitGraphParser.js';
import gitGraphDb from './gitGraphAst.js';
import gitGraphRenderer from './gitGraphRenderer.js';
import gitGraphStyles from './styles.js';
import type { DiagramDefinition } from '../../diagram-api/types.js';

export const diagram: DiagramDefinition = {
parser: gitGraphParser,
parser: parser,
db: gitGraphDb,
renderer: gitGraphRenderer,
styles: gitGraphStyles,
Expand Down
68 changes: 66 additions & 2 deletions packages/mermaid/src/diagrams/git/gitGraphParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,78 @@ import type { ParserDefinition } from '../../diagram-api/types.js';
import { log } from '../../logger.js';
import { populateCommonDb } from '../common/populateCommonDb.js';
import db from './gitGraphAst.js';
import { commitType } from './gitGraphAst.js';
import type {
CheckoutAst,
CherryPickingAst,
MergeAst,
CommitAst,
BranchAst,
} from './gitGraphTypes.js';

const populate = (ast: any) => {
const populate = (ast: GitGraph) => {
populateCommonDb(ast, db);
for (const statement of ast.statements) {
log.debug(statement);
parseStatement(statement);
}
};

const parseStatement = (statement: any) => {
switch (statement.$type) {
case 'Commit':
parseCommit(statement);
break;
case 'Branch':
parseBranch(statement);
break;
case 'Merge':
parseMerge(statement);
break;
case 'Checkout':
parseCheckout(statement);
break;
case 'CherryPicking':
parseCherryPicking(statement);
break;
default:
log.warn(`Unknown statement type`);
}
};

const parseCommit = (commit: CommitAst) => {
const id = commit.id;
const message = commit.message ?? '';
const tags = commit.tags ?? [];
const type = commit.type !== undefined ? commitType[commit.type] : 0;
db.commit(message, id, type, tags);
};

const parseBranch = (branch: BranchAst) => {
const name = branch.name;
const order = branch.order ?? 0;
db.branch(name, order);
};

const parseMerge = (merge: MergeAst) => {
const branch = merge.branch;
const id = merge.id ?? '';
const tags = merge.tags ?? [];
const type = merge.type !== undefined ? commitType[merge.type] : 0;
db.merge(branch, id, type, tags);
};

const parseCheckout = (checkout: CheckoutAst) => {
const branch = checkout.branch;
db.checkout(branch);
};

const parseCherryPicking = (cherryPicking: CherryPickingAst) => {
const id = cherryPicking.id;
const tags = cherryPicking.tags ?? [];
const parent = cherryPicking.parent;
db.cherryPick(id, '', tags, parent);
};

export const parser: ParserDefinition = {
parse: async (input: string): Promise<void> => {
const ast: GitGraph = await parse('gitGraph', input);
Expand Down
10 changes: 5 additions & 5 deletions packages/mermaid/src/diagrams/git/gitGraphTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export interface GitGraph {
statements: Statement[];
}

export type Statement = CommitAst | Branch | Merge | Checkout | CherryPicking;
export type Statement = CommitAst | BranchAst | MergeAst | CheckoutAst | CherryPickingAst;

export interface CommitAst {
$type: 'Commit';
Expand All @@ -26,26 +26,26 @@ export interface CommitAst {
type?: 'NORMAL' | 'REVERSE' | 'HIGHLIGHT';
}

export interface Branch {
export interface BranchAst {
$type: 'Branch';
name: string;
order?: number;
}

export interface Merge {
export interface MergeAst {
$type: 'Merge';
branch: string;
id?: string;
tags?: string[];
type?: 'NORMAL' | 'REVERSE' | 'HIGHLIGHT';
}

export interface Checkout {
export interface CheckoutAst {
$type: 'Checkout';
branch: string;
}

export interface CherryPicking {
export interface CherryPickingAst {
$type: 'CherryPicking';
id: string;
tags?: string[];
Expand Down
26 changes: 25 additions & 1 deletion packages/parser/src/language/gitGraph/gitGraph.langium
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
grammar GitGraph

import "../common/common";
interface Common {
accDescr?: string;
accTitle?: string;
title?: string;
}

fragment TitleAndAccessibilities:
((accDescr=ACC_DESCR | accTitle=ACC_TITLE | title=TITLE) EOL)+
;

fragment EOL returns string:
NEWLINE+ | EOF
;

terminal NEWLINE: /\r?\n/;
terminal ACC_DESCR: /[\t ]*accDescr(?:[\t ]*:([^\n\r]*?(?=%%)|[^\n\r]*)|\s*{([^}]*)})/;
terminal ACC_TITLE: /[\t ]*accTitle[\t ]*:(?:[^\n\r]*?(?=%%)|[^\n\r]*)/;
terminal TITLE: /[\t ]*title(?:[\t ][^\n\r]*?(?=%%)|[\t ][^\n\r]*|)/;

hidden terminal WHITESPACE: /[\t ]+/;
hidden terminal YAML: /---[\t ]*\r?\n(?:[\S\s]*?\r?\n)?---(?:\r?\n|(?!\S))/;
hidden terminal DIRECTIVE: /[\t ]*%%{[\S\s]*?}%%(?:\r?\n|(?!\S))/;
hidden terminal SINGLE_LINE_COMMENT: /[\t ]*%%[^\n\r]*/;

entry GitGraph:
NEWLINE*
Expand Down Expand Up @@ -62,6 +84,8 @@ CherryPicking:
|'parent:' id=STRING
)* EOL;



terminal INT returns number: /[0-9]+(?=\s)/;
terminal ID returns string: /\w([-\./\w]*[-\w])?/;
terminal STRING: /"[^"]*"|'[^']*'/;
Expand Down
14 changes: 13 additions & 1 deletion packages/parser/tests/gitGraph.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,23 @@ describe('gitGraph', () => {
const result = parse(`gitGraph`);
expect(result.value.$type).toBe(GitGraph);
expect(result.value.statements).toHaveLength(0);
expect(result.lexerErrors).toHaveLength(0);
expect(result.parserErrors).toHaveLength(0);
});

it('should handle gitGraph with one statement', () => {
const result = parse(`gitGraph\n A`);
const result = parse(`gitGraph\n commit\n`);
expect(result.value.$type).toBe(GitGraph);
expect(result.lexerErrors).toHaveLength(0);
expect(result.parserErrors).toHaveLength(0);
expect(result.value.statements).toHaveLength(1);
});

it('should handle gitGraph with multiple statements and use accTitle', () => {
const result = parse(`gitGraph\n commit\n commit\n accTitle: title\n commit\n`);
expect(result.value.$type).toBe(GitGraph);
expect(result.lexerErrors).toHaveLength(0);
expect(result.parserErrors).toHaveLength(0);
});
});
});

0 comments on commit d0eadeb

Please sign in to comment.