From 4974b4763bd60eb875f93a71dbe2fe82ecfed9fc Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 5 Sep 2009 16:29:23 +0200 Subject: Add semantic graph and traversal mechanism The parser now builds the semantic graph. --- cli/makefile | 15 ++ cli/parser.cxx | 233 +++++++++++++++++++++++- cli/parser.hxx | 16 +- cli/semantics.hxx | 16 ++ cli/semantics/class.cxx | 28 +++ cli/semantics/class.hxx | 25 +++ cli/semantics/elements.cxx | 117 ++++++++++++ cli/semantics/elements.hxx | 421 +++++++++++++++++++++++++++++++++++++++++++ cli/semantics/expression.cxx | 28 +++ cli/semantics/expression.hxx | 79 ++++++++ cli/semantics/namespace.cxx | 28 +++ cli/semantics/namespace.hxx | 25 +++ cli/semantics/option.cxx | 48 +++++ cli/semantics/option.hxx | 168 +++++++++++++++++ cli/semantics/unit.cxx | 64 +++++++ cli/semantics/unit.hxx | 298 ++++++++++++++++++++++++++++++ cli/traversal.hxx | 16 ++ cli/traversal/class.cxx | 27 +++ cli/traversal/class.hxx | 27 +++ cli/traversal/elements.cxx | 15 ++ cli/traversal/elements.hxx | 143 +++++++++++++++ cli/traversal/expression.hxx | 17 ++ cli/traversal/namespace.cxx | 27 +++ cli/traversal/namespace.hxx | 27 +++ cli/traversal/option.cxx | 60 ++++++ cli/traversal/option.hxx | 75 ++++++++ cli/traversal/unit.cxx | 47 +++++ cli/traversal/unit.hxx | 59 ++++++ 28 files changed, 2137 insertions(+), 12 deletions(-) create mode 100644 cli/semantics.hxx create mode 100644 cli/semantics/class.cxx create mode 100644 cli/semantics/class.hxx create mode 100644 cli/semantics/elements.cxx create mode 100644 cli/semantics/elements.hxx create mode 100644 cli/semantics/expression.cxx create mode 100644 cli/semantics/expression.hxx create mode 100644 cli/semantics/namespace.cxx create mode 100644 cli/semantics/namespace.hxx create mode 100644 cli/semantics/option.cxx create mode 100644 cli/semantics/option.hxx create mode 100644 cli/semantics/unit.cxx create mode 100644 cli/semantics/unit.hxx create mode 100644 cli/traversal.hxx create mode 100644 cli/traversal/class.cxx create mode 100644 cli/traversal/class.hxx create mode 100644 cli/traversal/elements.cxx create mode 100644 cli/traversal/elements.hxx create mode 100644 cli/traversal/expression.hxx create mode 100644 cli/traversal/namespace.cxx create mode 100644 cli/traversal/namespace.hxx create mode 100644 cli/traversal/option.cxx create mode 100644 cli/traversal/option.hxx create mode 100644 cli/traversal/unit.cxx create mode 100644 cli/traversal/unit.hxx (limited to 'cli') diff --git a/cli/makefile b/cli/makefile index e2158d4..76d23d8 100644 --- a/cli/makefile +++ b/cli/makefile @@ -7,6 +7,21 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make cxx_tun := cli.cxx lexer.cxx parser.cxx +cxx_tun += \ +semantics/class.cxx \ +semantics/elements.cxx \ +semantics/expression.cxx \ +semantics/namespace.cxx \ +semantics/option.cxx \ +semantics/unit.cxx + +cxx_tun += \ +traversal/class.cxx \ +traversal/elements.cxx \ +traversal/namespace.cxx \ +traversal/option.cxx \ +traversal/unit.cxx + # # cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o)) diff --git a/cli/parser.cxx b/cli/parser.cxx index 82a68dc..9b9c116 100644 --- a/cli/parser.cxx +++ b/cli/parser.cxx @@ -9,7 +9,10 @@ #include "lexer.hxx" #include "parser.hxx" +#include "semantics.hxx" + using namespace std; +using namespace semantics; const char* keywords[] = { @@ -120,17 +123,24 @@ recover (token& t) } } -void parser:: +auto_ptr parser:: parse (std::istream& is, std::string const& id) { + auto_ptr unit (new cli_unit (id)); + unit_ = unit.get (); + lexer l (is, id); lexer_ = &l; + id_ = &id; valid_ = true; + def_unit (); if (!valid_ || !l.valid ()) throw invalid_input (); + + return unit; } void parser:: @@ -154,6 +164,9 @@ def_unit () } } + scope* old (scope_); + scope_ = unit_; + // decl-seq // while (t.type () != token::t_eos) @@ -177,6 +190,8 @@ def_unit () break; // Non-recoverable error. } } + + scope_ = old; } void parser:: @@ -191,6 +206,12 @@ include_decl () throw error (); } + if (valid_) + { + cxx_unit& n (unit_->new_node (*id_, t.line (), t.column ())); + unit_->new_edge (*unit_, n, t.literal ()); + } + t = lexer_->next (); if (t.punctuation () != token::p_semi) @@ -237,6 +258,16 @@ namespace_def () throw error (); } + scope* old (scope_); + + if (valid_) + { + namespace_& n ( + unit_->new_node (*id_, t.line (), t.column ())); + unit_->new_edge (*scope_, n, t.identifier ()); + scope_ = &n; + } + t = lexer_->next (); if (t.punctuation () != token::p_lcbrace) @@ -253,6 +284,8 @@ namespace_def () while (decl (t)) t = lexer_->next (); + scope_ = old; + if (t.punctuation () != token::p_rcbrace) { cerr << *id_ << ':' << t.line () << ':' << t.column () << ": error: " @@ -274,6 +307,15 @@ class_def () throw error (); } + scope* old (scope_); + + if (valid_) + { + class_& n (unit_->new_node (*id_, t.line (), t.column ())); + unit_->new_edge (*scope_, n, t.identifier ()); + scope_ = &n; + } + t = lexer_->next (); if (t.punctuation () != token::p_lcbrace) @@ -303,6 +345,8 @@ class_def () } } + scope_ = old; + if (t.punctuation () != token::p_rcbrace) { cerr << *id_ << ':' << t.line () << ':' << t.column () << ": error: " @@ -323,23 +367,46 @@ class_def () bool parser:: option_def (token& t) { + size_t l (t.line ()), c (t.column ()); + // type-spec // // These two functions set t to the next token if they return // true. // - if (!qualified_name (t) && !fundamental_type (t)) + string type_name; + + if (!qualified_name (t, type_name) && !fundamental_type (t, type_name)) return false; + option* o (0); + + if (valid_) + { + o = &unit_->new_node