summaryrefslogtreecommitdiffstats
path: root/src/Lang/Cpp/CppParseTree.ts
diff options
context:
space:
mode:
authorRowan Goemans <RB.Goemans@student.han.nl>2017-12-31 04:07:55 +0100
committerChristoph Schlosser <christophschlosser@users.noreply.github.com>2018-02-20 22:02:22 +0100
commit31f6517aa5d8d3ccdd0b39880337c000943d08c1 (patch)
tree2c3c5240470a592f4c0bd134d779f4f3c25d6b2b /src/Lang/Cpp/CppParseTree.ts
parent10aac7196a3a701860525d0f466896efe182d39a (diff)
downloaddoxdocgen-31f6517aa5d8d3ccdd0b39880337c000943d08c1.tar.gz
-- Completed unit tests for operators. Conversion operators aren't working yet.
-- Renamed all C things to Cpp since that is really what they are. -- Made empty files for the remaining unit tests.
Diffstat (limited to 'src/Lang/Cpp/CppParseTree.ts')
-rw-r--r--src/Lang/Cpp/CppParseTree.ts124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/Lang/Cpp/CppParseTree.ts b/src/Lang/Cpp/CppParseTree.ts
new file mode 100644
index 0000000..41fb8b2
--- /dev/null
+++ b/src/Lang/Cpp/CppParseTree.ts
@@ -0,0 +1,124 @@
+import { CppToken, CppTokenType } from "./CppToken";
+
+export class CppParseTree {
+
+ /**
+ * Create a tree from CppTokens. This consumes the CppTokens.
+ * @param CppTokens The CppTokens to create a tree for.
+ * @param inNested If currently allready nesting.
+ */
+ public static CreateTree(CppTokens: CppToken[], inNested: boolean = false): CppParseTree {
+ const tree: CppParseTree = new CppParseTree();
+
+ while (CppTokens.length > 0) {
+ const token: CppToken = CppTokens.shift();
+ switch (token.type) {
+ case CppTokenType.OpenParenthesis:
+ tree.nodes.push(this.CreateTree(CppTokens, true));
+ break;
+ case CppTokenType.CloseParenthesis:
+ if (inNested === false) {
+ throw new Error("Unmatched closing parenthesis.");
+ }
+ return tree;
+ default:
+ tree.nodes.push(token);
+ break;
+ }
+ }
+
+ if (inNested === true) {
+ throw new Error("No match found for an opening parenthesis.");
+ }
+
+ return tree;
+ }
+
+ public nodes: Array<CppToken | CppParseTree> = [];
+
+ /**
+ * Compact empty branches. Example ((foo))(((bar))) will become (foo)(bar)
+ * @param tree The CppParseTree to compact. Defaults to the current tree.
+ */
+ public Compact(tree: CppParseTree = this): CppParseTree {
+ const newTree: CppParseTree = new CppParseTree();
+ newTree.nodes = tree.nodes.map((n) => n);
+ const isNotCompact = (n) => {
+ return n instanceof CppParseTree
+ && n.nodes.length === 1 && n.nodes[0] instanceof CppParseTree;
+ };
+
+ // Compact current level of nodes to the maximum amount.
+ while (newTree.nodes.some((n) => isNotCompact(n))) {
+ newTree.nodes = newTree.nodes
+ .map((n) => n instanceof CppParseTree && isNotCompact(n) ? n.nodes[0] : n);
+ }
+
+ // Compact all nested CppParseTrees.
+ newTree.nodes = newTree.nodes
+ .map((n) => n instanceof CppParseTree ? this.Compact(n) : n);
+
+ return newTree;
+ }
+
+ /**
+ * Copy CppParseTree.
+ * @param tree The CppParseTree to compact. Defaults to the current tree.
+ */
+ public Copy(tree: CppParseTree = this): CppParseTree {
+ const newTree: CppParseTree = new CppParseTree();
+ newTree.nodes = tree.nodes
+ .map((n) => n instanceof CppToken ? n : this.Copy(n));
+ return newTree;
+ }
+
+ /**
+ * Create string from the CppParseTree which is a representation of the original code.
+ * @param tree The CppParseTree to compact. Defaults to the current tree.
+ */
+ public Yield(tree: CppParseTree = this): string {
+ let code: string = "";
+
+ for (const node of tree.nodes) {
+ if (node instanceof CppParseTree) {
+ code += "(" + this.Yield(node) + ")";
+ continue;
+ }
+
+ switch (node.type) {
+ case CppTokenType.Symbol:
+ code += code === "" ? node.value : " " + node.value;
+ break;
+ case CppTokenType.Pointer:
+ code += node.value;
+ break;
+ case CppTokenType.Reference:
+ code += node.value;
+ break;
+ case CppTokenType.ArraySubscript:
+ code += node.value;
+ break;
+ case CppTokenType.CurlyBlock:
+ code += node.value;
+ break;
+ case CppTokenType.Assignment:
+ code += " " + node.value;
+ break;
+ case CppTokenType.Comma:
+ code += node.value;
+ break;
+ case CppTokenType.Arrow:
+ code += " " + node.value;
+ break;
+ case CppTokenType.Ellipsis:
+ code += node.value;
+ break;
+ case CppTokenType.Attribute:
+ code += code === "" ? node.value : " " + node.value;
+ break;
+ }
+ }
+
+ return code;
+ }
+}