about summary refs log tree commit diff
path: root/src/fix-ng/parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/fix-ng/parser.cc')
-rw-r--r--src/fix-ng/parser.cc76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/fix-ng/parser.cc b/src/fix-ng/parser.cc
new file mode 100644
index 000000000000..b2f0ed05df50
--- /dev/null
+++ b/src/fix-ng/parser.cc
@@ -0,0 +1,76 @@
+extern "C" {
+#include <sglr.h>
+#include <asfix2.h>
+}
+
+#include "parser.hh"
+#include "shared.hh"
+#include "expr.hh"
+#include "parse-table.h"
+
+
+Expr parseExprFromFile(const Path & path)
+{
+    /* Perhaps this is already an imploded parse tree? */
+    Expr e = ATreadFromNamedFile(path.c_str());
+    if (e) return e;
+
+    /* Initialise the SDF libraries. */
+    static bool initialised = false;
+    static ATerm parseTable = 0;
+    static language lang = 0;
+
+    if (!initialised) {
+        PT_initMEPTApi();
+        PT_initAsFix2Api();
+        SGinitParser(ATfalse);
+
+        ATprotect(&parseTable);
+        parseTable = ATreadFromBinaryString(
+            (char *) fixParseTable, sizeof fixParseTable);
+        if (!parseTable)
+            throw Error(format("cannot construct parse table term"));
+
+        ATprotect(&lang);
+        lang = ATmake("Fix");
+        if (!SGopenLanguageFromTerm(
+                (char *) programId.c_str(), lang, parseTable))
+            throw Error(format("cannot open language"));
+
+        SG_STARTSYMBOL_ON();
+        SG_OUTPUT_ON();
+        SG_ASFIX2ME_ON();
+        SG_AMBIGUITY_ERROR_ON();
+
+        initialised = true;
+    }
+
+    ATerm result = SGparseFile((char *) programId.c_str(), lang,
+        "Expr", (char *) path.c_str());
+    if (!result)
+        throw SysError(format("parse failed in `%1%'") % path);
+    if (SGisParseError(result))
+        throw Error(format("parse error in `%1%': %2%")
+            % path % printTerm(result));
+
+    PT_ParseTree tree = PT_makeParseTreeFromTerm(result);
+    if (!tree)
+        throw Error(format("cannot create parse tree"));
+    
+    ATerm imploded = PT_implodeParseTree(tree,
+        ATtrue,
+        ATtrue,
+        ATtrue,
+        ATtrue,
+        ATtrue,
+        ATtrue,
+        ATfalse,
+        ATtrue,
+        ATtrue,
+        ATtrue,
+        ATfalse);
+    if (!imploded)
+        throw Error(format("cannot implode parse tree"));
+
+    return imploded;
+}