summaryrefslogtreecommitdiff
path: root/cli/parser.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'cli/parser.cxx')
-rw-r--r--cli/parser.cxx233
1 files changed, 225 insertions, 8 deletions
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<cli_unit> parser::
parse (std::istream& is, std::string const& id)
{
+ auto_ptr<cli_unit> 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<cxx_unit> (*id_, t.line (), t.column ()));
+ unit_->new_edge<cxx_includes> (*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<namespace_> (*id_, t.line (), t.column ()));
+ unit_->new_edge<names> (*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<class_> (*id_, t.line (), t.column ()));
+ unit_->new_edge<names> (*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<option> (*id_, l, c);
+ type& t (unit_->new_type (*id_, l, c, type_name));
+ unit_->new_edge<belongs> (*o, t);
+ }
+
// option-name-seq
//
+ names::name_list nl;
while (true)
{
switch (t.type ())
{
case token::t_identifier:
+ {
+ if (valid_)
+ nl.push_back (t.identifier ());
+
+ break;
+ }
case token::t_string_lit:
{
+ if (valid_)
+ nl.push_back (t.literal ());
+
break;
}
default:
@@ -358,28 +425,70 @@ option_def (token& t)
break;
}
+ if (valid_)
+ unit_->new_edge<names> (*scope_, *o, nl);
+
// initializer
//
+ std::string ev;
+ expression::expression_type et;
+
if (t.punctuation () == token::p_eq)
{
- t = lexer_->next ();
-
// assignment initiaizer
//
- if (qualified_name (t))
+ t = lexer_->next ();
+
+ l = t.line ();
+ c = t.column ();
+
+ if (qualified_name (t, ev))
{
+ et = expression::identifier;
}
else
{
switch (t.type ())
{
case token::t_string_lit:
+ {
+ ev = t.literal ();
+ et = expression::string_lit;
+ t = lexer_->next ();
+ break;
+ }
case token::t_char_lit:
+ {
+ ev = t.literal ();
+ et = expression::char_lit;
+ t = lexer_->next ();
+ break;
+ }
case token::t_bool_lit:
+ {
+ ev = t.literal ();
+ et = expression::bool_lit;
+ t = lexer_->next ();
+ break;
+ }
case token::t_int_lit:
+ {
+ ev = t.literal ();
+ et = expression::int_lit;
+ t = lexer_->next ();
+ break;
+ }
case token::t_float_lit:
+ {
+ ev = t.literal ();
+ et = expression::float_lit;
+ t = lexer_->next ();
+ break;
+ }
case token::t_call_expr:
{
+ ev = t.expression ();
+ et = expression::call_expr;
t = lexer_->next ();
break;
}
@@ -396,9 +505,20 @@ option_def (token& t)
{
// c-tor initializer
//
+ l = t.line ();
+ c = t.column ();
+
+ ev = t.expression ();
+ et = expression::call_expr;
t = lexer_->next ();
}
+ if (valid_ && !ev.empty ())
+ {
+ expression& e (unit_->new_node<expression> (*id_, l, c, et, ev));
+ unit_->new_edge<initialized> (*o, e);
+ }
+
if (t.punctuation () != token::p_semi)
{
cerr << *id_ << ':' << t.line () << ':' << t.column () << ": error: "
@@ -410,13 +530,18 @@ option_def (token& t)
}
bool parser::
-qualified_name (token& t)
+qualified_name (token& t, string& r)
{
if (t.type () != token::t_identifier && t.punctuation () != token::p_dcolon)
return false;
+ r.clear ();
+
if (t.punctuation () == token::p_dcolon)
+ {
+ r += "::";
t = lexer_->next ();
+ }
while (true)
{
@@ -427,17 +552,22 @@ qualified_name (token& t)
throw error ();
}
+ r += t.identifier ();
t = lexer_->next ();
if (t.type () == token::t_template_expr)
{
// Template-id.
//
+ r += t.expression ();
t = lexer_->next ();
}
if (t.punctuation () == token::p_dcolon)
+ {
+ r += "::";
t = lexer_->next ();
+ }
else
break;
}
@@ -446,21 +576,26 @@ qualified_name (token& t)
}
bool parser::
-fundamental_type (token& t)
+fundamental_type (token& t, string& r)
{
+ r.clear ();
+
switch (t.keyword ())
{
case token::k_signed:
case token::k_unsigned:
{
+ r = t.keyword () == token::k_signed ? "signed" : "unsigned";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_short:
{
+ r += " short";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_int:
{
+ r += " int";
t = lexer_->next ();
}
default:
@@ -470,19 +605,23 @@ fundamental_type (token& t)
}
case token::k_long:
{
+ r += " long";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_int:
{
+ r += " int";
t = lexer_->next ();
break;
}
case token::k_long:
{
+ r += " long";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_int:
{
+ r += " int";
t = lexer_->next ();
}
default:
@@ -497,19 +636,23 @@ fundamental_type (token& t)
}
case token::k_int:
{
+ r += " int";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_short:
{
+ r += " short";
t = lexer_->next ();
break;
}
case token::k_long:
{
+ r += " long";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_long:
{
+ r += " long";
t = lexer_->next ();
}
default:
@@ -524,6 +667,7 @@ fundamental_type (token& t)
}
case token::k_char:
{
+ r += " char";
t = lexer_->next ();
break;
}
@@ -536,16 +680,19 @@ fundamental_type (token& t)
case token::k_long:
{
bool l (t.keyword () == token::k_long);
+ r = l ? "long" : "short";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_signed:
case token::k_unsigned:
{
+ r += t.keyword () == token::k_signed ? " signed" : " unsigned";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_int:
{
+ r += " int";
t = lexer_->next ();
}
default:
@@ -555,15 +702,18 @@ fundamental_type (token& t)
}
case token::k_long:
{
+ r += " long";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_signed:
case token::k_unsigned:
{
+ r += t.keyword () == token::k_signed ? " signed" : " unsigned";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_int:
{
+ r += " int";
t = lexer_->next ();
}
default:
@@ -573,12 +723,20 @@ fundamental_type (token& t)
}
case token::k_int:
{
+ r += " int";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_signed:
+ {
+ r += " signed";
+ t = lexer_->next ();
+ break;
+ }
case token::k_unsigned:
{
+ r += " unsigned";
t = lexer_->next ();
+ break;
}
default:
break;
@@ -592,12 +750,20 @@ fundamental_type (token& t)
}
case token::k_int:
{
+ r += " int";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_signed:
+ {
+ r += " signed";
+ t = lexer_->next ();
+ break;
+ }
case token::k_unsigned:
{
+ r += " unsigned";
t = lexer_->next ();
+ break;
}
default:
break;
@@ -607,8 +773,10 @@ fundamental_type (token& t)
case token::k_double:
{
if (l)
+ {
+ r += " double";
t = lexer_->next ();
-
+ }
break;
}
default:
@@ -618,24 +786,29 @@ fundamental_type (token& t)
}
case token::k_int:
{
+ r = "int";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_signed:
case token::k_unsigned:
{
+ r += t.keyword () == token::k_signed ? " signed" : " unsigned";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_short:
{
+ r += " short";
t = lexer_->next ();
break;
}
case token::k_long:
{
+ r += " long";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_long:
{
+ r += " long";
t = lexer_->next ();
}
default:
@@ -649,12 +822,20 @@ fundamental_type (token& t)
}
case token::k_short:
{
+ r += " short";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_signed:
+ {
+ r += " signed";
+ t = lexer_->next ();
+ break;
+ }
case token::k_unsigned:
{
+ r += " unsigned";
t = lexer_->next ();
+ break;
}
default:
break;
@@ -663,22 +844,37 @@ fundamental_type (token& t)
}
case token::k_long:
{
+ r += " long";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_signed:
+ {
+ r += " signed";
+ t = lexer_->next ();
+ break;
+ }
case token::k_unsigned:
{
+ r += " unsigned";
t = lexer_->next ();
break;
}
case token::k_long:
{
+ r += " long";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_signed:
+ {
+ r += " signed";
+ t = lexer_->next ();
+ break;
+ }
case token::k_unsigned:
{
+ r += " unsigned";
t = lexer_->next ();
+ break;
}
default:
break;
@@ -697,12 +893,20 @@ fundamental_type (token& t)
}
case token::k_char:
{
+ r = "char";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_signed:
+ {
+ r += " signed";
+ t = lexer_->next ();
+ break;
+ }
case token::k_unsigned:
{
+ r += " unsigned";
t = lexer_->next ();
+ break;
}
default:
break;
@@ -710,18 +914,31 @@ fundamental_type (token& t)
break;
}
case token::k_bool:
+ {
+ r = "bool";
+ t = lexer_->next ();
+ break;
+ }
case token::k_wchar:
+ {
+ r = "wchar_t";
+ t = lexer_->next ();
+ break;
+ }
case token::k_float:
{
+ r = "float";
t = lexer_->next ();
break;
}
case token::k_double:
{
+ r = "double";
switch ((t = lexer_->next ()).keyword ())
{
case token::k_long:
{
+ r += " long";
t = lexer_->next ();
}
default: