about summary refs log tree commit diff
path: root/src/fix-ng/parser.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2003-10-29T16·05+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2003-10-29T16·05+0000
commitb95a3dc45bcbbe8a0985bab82146ed00afcf0239 (patch)
tree75ec3e901b3af65a814770aae807c790d20eff1d /src/fix-ng/parser.cc
parent4d728f6a36c83ff684426788df775b385fae9e88 (diff)
* Basic grammar and parser for the Fix language. We use libsglr and
  friends to do the parsing.  The parse table is embedded in the Fix
  executable using bin2c, which converts an arbitrary file into a C
  character array.

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;
+}