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/parser.cxx | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 225 insertions(+), 8 deletions(-) (limited to 'cli/parser.cxx') 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