added parser

This commit is contained in:
Austin Fulbright
2024-07-25 05:25:19 -04:00
parent 1a95d48852
commit d0eadebb99
5 changed files with 111 additions and 11 deletions

View File

@@ -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,

View File

@@ -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);

View File

@@ -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';
@@ -26,13 +26,13 @@ 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;
@@ -40,12 +40,12 @@ export interface Merge {
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[];

View File

@@ -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*
@@ -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: /"[^"]*"|'[^']*'/;

View File

@@ -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);
});
});
});