summaryrefslogtreecommitdiffstats
path: root/semtest.cxx
diff options
context:
space:
mode:
authorfche <fche>2005-03-02 01:28:50 +0000
committerfche <fche>2005-03-02 01:28:50 +0000
commit56099f083d7a68722ace316be4d288d21caabaee (patch)
tree3e67ec78134a358c1f90f701c165c4c577d62177 /semtest.cxx
parent2f1a1aead38c1dcd329a694dd8d3290b37320466 (diff)
downloadsystemtap-steved-56099f083d7a68722ace316be4d288d21caabaee.tar.gz
systemtap-steved-56099f083d7a68722ace316be4d288d21caabaee.tar.xz
systemtap-steved-56099f083d7a68722ace316be4d288d21caabaee.zip
* some semantic analysis
2005-03-01 Frank Ch. Eigler <fche@redhat.com> * parse.cxx: Implement left-associativity for several types of operators. Add some more statement types. Parse functions. Be able to print tokens. Simplify error generating functions. Save tokens in all parse tree nodes. * parse.h: Corresponding changes. * staptree.cxx: Move tree-printing functions here. Add many new functions for symbol and type resolution. * staptree.h: Corresponding changes. * semtest.cxx: New semantic analysis pass & test driver. * testsuite/sem*/*: New tests. * parsetest.cxx: Separated parse test driver. * testsuite/parse*/*: Adapt tests to parsetest driver. * Makefile.am: Build semtest. Run its tests. * Makefile.in: Regenerated. * parse.cxx, parse.h: New files: parser.
Diffstat (limited to 'semtest.cxx')
-rw-r--r--semtest.cxx185
1 files changed, 185 insertions, 0 deletions
diff --git a/semtest.cxx b/semtest.cxx
new file mode 100644
index 00000000..f86d17ca
--- /dev/null
+++ b/semtest.cxx
@@ -0,0 +1,185 @@
+// semantic analysis pass, beginnings of elaboration
+// Copyright 2005 Red Hat Inc.
+// GPL
+
+#include "staptree.h"
+#include "parse.h"
+#include <iostream>
+
+
+int
+semantic_pass_1 (vector<stapfile*>& files)
+{
+ int rc = 0;
+
+ // link up symbols to their declarations
+ for (unsigned i=0; i<files.size(); i++)
+ {
+ stapfile* f = files[i];
+
+ // ... on functions
+ for (unsigned j=0; j<f->functions.size(); j++)
+ {
+ functiondecl* fn = f->functions[j];
+ symresolution_info ri (fn->locals, f->globals, files, f, fn);
+
+ fn->body->resolve_symbols (ri);
+ if (ri.num_unresolved)
+ rc ++;
+ }
+
+ // ... and on probes
+ for (unsigned j=0; j<f->probes.size(); j++)
+ {
+ probe* pn = f->probes[j];
+ symresolution_info ri (pn->locals, f->globals, files, f);
+
+ pn->body->resolve_symbols (ri);
+ if (ri.num_unresolved)
+ rc ++;
+ }
+ }
+
+ return rc;
+}
+
+
+int
+semantic_pass_2 (vector<stapfile*>& files)
+{
+ int rc = 0;
+
+ // next pass: type inference
+ unsigned iterations = 0;
+ typeresolution_info ti;
+
+ ti.assert_resolvability = false;
+ while (1)
+ {
+ iterations ++;
+ // cerr << "Type resolution, iteration " << iterations << endl;
+ ti.num_newly_resolved = 0;
+ ti.num_still_unresolved = 0;
+
+ for (unsigned i=0; i<files.size(); i++)
+ {
+ stapfile* f = files[i];
+
+ for (unsigned j=0; j<f->functions.size(); j++)
+ {
+ functiondecl* fn = f->functions[j];
+ ti.current_function = fn;
+ fn->body->resolve_types (ti);
+ if (fn->type == pe_unknown)
+ ti.unresolved (fn->tok);
+ }
+
+ for (unsigned j=0; j<f->probes.size(); j++)
+ {
+ probe* pn = f->probes[j];
+ ti.current_function = 0;
+ pn->body->resolve_types (ti);
+ }
+
+ for (unsigned j=0; j<f->globals.size(); j++)
+ {
+ vardecl* gd = f->globals[j];
+ if (gd->type == pe_unknown)
+ ti.unresolved (gd->tok);
+ }
+ }
+
+ if (ti.num_newly_resolved == 0) // converged
+ if (ti.num_still_unresolved == 0)
+ break; // successfully
+ else if (! ti.assert_resolvability)
+ ti.assert_resolvability = true; // last pass, with error msgs
+ else
+ { // unsuccessful conclusion
+ rc ++;
+ break;
+ }
+ }
+
+ return rc;
+}
+
+
+int
+main (int argc, char *argv [])
+{
+ int rc = 0;
+
+ vector<stapfile*> files;
+ if (argc == 1)
+ {
+ parser p (cin);
+ stapfile* f = p.parse ();
+ if (f)
+ files.push_back (f);
+ else
+ rc ++;
+ }
+ else for (int i = 1; i < argc; i ++)
+ {
+ parser p (argv[i]);
+ stapfile* f = p.parse ();
+ if (f)
+ files.push_back (f);
+ else
+ rc ++;
+ }
+
+ rc += semantic_pass_1 (files);
+ rc += semantic_pass_2 (files);
+
+ if (argc == 1) // processed stdin only
+ {
+ for (unsigned i=0; i<files.size(); i++)
+ {
+ stapfile* f = files[i];
+ for (unsigned j=0; j<f->functions.size(); j++)
+ {
+ functiondecl* fn = f->functions[j];
+ cerr << "Function ";
+ fn->printsig (cerr);
+ cerr << endl << "locals:" << endl;
+ for (unsigned k=0; k<fn->locals.size(); k++)
+ {
+ vardecl* fa = fn->locals[k];
+ cerr << "\t";
+ fa->printsig (cerr);
+ cerr << endl;
+ }
+ cerr << endl;
+ }
+
+ for (unsigned j=0; j<f->probes.size(); j++)
+ {
+ probe* pn = f->probes[j];
+ cerr << "Probe " << *pn->tok << endl; // XXX: print probespec
+ cerr << "locals:" << endl;
+ for (unsigned k=0; k<pn->locals.size(); k++)
+ {
+ vardecl* fa = pn->locals[k];
+ cerr << "\t";
+ fa->printsig (cerr);
+ cerr << endl;
+ }
+ cerr << endl;
+ }
+
+ cerr << "globals:" << endl;
+ for (unsigned k=0; k<f->globals.size(); k++)
+ {
+ vardecl* fa = f->globals[k];
+ cerr << "\t";
+ fa->printsig (cerr);
+ cerr << endl;
+ }
+ cerr << endl;
+ }
+ }
+
+ return rc;
+}