aboutsummaryrefslogtreecommitdiff
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 000000000..b2f0ed05d
--- /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;
+}