@flowscripter/mpeg-sdl-parser
Version:
ISO/IEC 14496-34 Syntactic Description Language (MPEG SDL) parser implemented in TypeScript
99 lines (86 loc) • 2.74 kB
text/typescript
import { AstPath, type Doc, doc } from "prettier";
import { getDocWithTrivia } from "./print_utils";
import type { AbstractNode } from "../ast/node/AbstractNode";
import type { StringDefinition } from "../ast/node/StringDefinition";
import type { StringLiteral } from "../ast/node/StringLiteral";
const { join } = doc.builders;
export function printStringDefinition(
path: AstPath<StringDefinition>,
print: (path: AstPath<AbstractNode>) => Doc,
): Doc {
const stringDefinition = path.node;
const elements = [];
if (stringDefinition.isReserved) {
elements.push(getDocWithTrivia(stringDefinition.reservedKeyword!));
}
if (stringDefinition.isLegacy) {
elements.push(getDocWithTrivia(stringDefinition.legacyKeyword!));
}
if (stringDefinition.isConst) {
elements.push(getDocWithTrivia(stringDefinition.constKeyword!));
}
if (stringDefinition.alignedModifier !== undefined) {
elements.push(
path.call(
print,
"alignedModifier" as keyof StringDefinition["alignedModifier"],
),
);
}
elements.push(getDocWithTrivia(stringDefinition.stringVariableKindToken));
elements.push(path.call(print, "identifier"));
if (stringDefinition.assignmentPunctuator !== undefined) {
elements.push(getDocWithTrivia(stringDefinition.assignmentPunctuator));
elements.push(
path.call(
print,
"stringLiteral" as keyof StringDefinition["stringLiteral"],
),
);
}
return [
join(" ", elements),
getDocWithTrivia(stringDefinition.semicolonPunctuator),
];
}
export function printStringLiteral(
path: AstPath<StringLiteral>,
): Doc {
const stringLiteral = path.node;
const stringLiterals = [];
let opened = false;
let currentLiteral = [] as Doc[];
let containsContent = false;
for (const literal of stringLiteral.literals) {
if (literal.text === '"') {
if (!opened) {
currentLiteral.push(...getDocWithTrivia(literal));
opened = true;
} else {
currentLiteral.push(...getDocWithTrivia(literal));
// avoid empty string literals after the first one
if ((stringLiterals.length === 0) || containsContent) {
stringLiterals.push(currentLiteral);
}
// reset state
currentLiteral = [];
containsContent = false;
opened = false;
}
} else if (literal.text === "u") {
if (opened) {
currentLiteral.push(literal.text);
containsContent = true;
} else {
currentLiteral.push(...getDocWithTrivia(literal));
}
} else if (literal.text.length > 0) {
currentLiteral.push(literal.text);
containsContent = true;
}
}
return join(
" ",
stringLiterals,
);
}