summaryrefslogtreecommitdiffstats
path: root/parse.cxx
diff options
context:
space:
mode:
authorfche <fche>2005-05-05 20:31:53 +0000
committerfche <fche>2005-05-05 20:31:53 +0000
commit829198553c89ca7f2da93559c61c04ee89079ea1 (patch)
tree2f23d20d3d6d1c4078cbb50fc8f35d323e922cde /parse.cxx
parente3f6c9cdd804120df4ec0b0fa33c033371958f17 (diff)
downloadsystemtap-steved-829198553c89ca7f2da93559c61c04ee89079ea1.tar.gz
systemtap-steved-829198553c89ca7f2da93559c61c04ee89079ea1.tar.xz
systemtap-steved-829198553c89ca7f2da93559c61c04ee89079ea1.zip
* preliminaries for code generation logic
2005-05-05 Frank Ch. Eigler <fche@redhat.com> * parse.cxx (parse): Add helper methods. (lexer::scan, parse_assignment): Parse "<<<" operator. Fix assignment associativity. (parse_symbol): Permit function with empty arg list. (parse_global, parse_statement, parse_functiondecl): Expect unconsumed leading keyword. (parse_global): Don't use ";" termination. * parse.h: Corresponding changes. * staptree.cxx (binary_expression::resolve_types): Fix <<< type inference. (translator_output): Improve pretty-printing. (*): Add general visitors to statement/expression types. * staptree.h: Corresponding changes. Tweak symresolution_info fields. Add semantic_error class. * semtest.cxx: Adapt to this. * testsuite/parseok/two.stp, semok/*.stp: Adapt to syntax changes.
Diffstat (limited to 'parse.cxx')
-rw-r--r--parse.cxx115
1 files changed, 73 insertions, 42 deletions
diff --git a/parse.cxx b/parse.cxx
index 91600e25..b5881331 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -32,6 +32,22 @@ parser::~parser()
}
+stapfile*
+parser::parse (std::istream& i)
+{
+ parser p (i);
+ return p.parse ();
+}
+
+
+stapfile*
+parser::parse (const std::string& n)
+{
+ parser p (n);
+ return p.parse ();
+}
+
+
ostream&
operator << (ostream& o, const token& t)
{
@@ -257,7 +273,15 @@ lexer::scan ()
(c == ':' && c2 == ':') ||
(c == '-' && c2 == '>') ||
false) // XXX: etc.
- n->content.push_back((char) input_get ());
+ n->content.push_back ((char) input_get ());
+
+ // handle three-character operator
+ if (c == '<' && c2 == '<')
+ {
+ int c3 = input.peek ();
+ if (c3 == '<')
+ n->content.push_back ((char) input_get ());
+ }
return n;
}
@@ -291,21 +315,11 @@ parser::parse ()
empty = false;
if (t->type == tok_identifier && t->content == "probe")
- {
- next ();
- f->probes.push_back (parse_probe ());
- }
+ f->probes.push_back (parse_probe ());
else if (t->type == tok_identifier && t->content == "global")
- {
- next ();
- parse_global (f->globals);
- }
+ parse_global (f->globals);
else if (t->type == tok_identifier && t->content == "function")
- {
- next ();
- f->functions.push_back (parse_functiondecl ());
- // XXX: check for duplicate function decl
- }
+ f->functions.push_back (parse_functiondecl ());
else
throw parse_error ("expected 'probe', 'global', or 'function'");
}
@@ -345,13 +359,18 @@ parser::parse ()
probe*
parser::parse_probe ()
{
+ const token* t0 = next ();
+ if (! (t0->type == tok_identifier && t0->content == "probe"))
+ throw parse_error ("expected 'probe'");
+
probe *p = new probe;
+ p->tok = t0;
+
while (1)
{
const token *t = peek ();
if (t && t->type == tok_identifier)
{
- p->tok = t;
p->locations.push_back (parse_probe_point ());
t = peek ();
@@ -467,6 +486,10 @@ parser::parse_statement ()
void
parser::parse_global (vector <vardecl*>& globals)
{
+ const token* t0 = next ();
+ if (! (t0->type == tok_identifier && t0->content == "global"))
+ throw parse_error ("expected 'global'");
+
while (1)
{
const token* t = next ();
@@ -478,13 +501,14 @@ parser::parse_global (vector <vardecl*>& globals)
d->tok = t;
globals.push_back (d); // XXX: check for duplicates
- t = next ();
- if (t->type == tok_operator && t->content == ";")
- break;
- else if (t->type == tok_operator && t->content == ",")
- continue;
+ t = peek ();
+ if (t && t->type == tok_operator && t->content == ",")
+ {
+ next ();
+ continue;
+ }
else
- throw parse_error ("expected ';' or ','");
+ break;
}
}
@@ -492,9 +516,13 @@ parser::parse_global (vector <vardecl*>& globals)
functiondecl*
parser::parse_functiondecl ()
{
+ const token* t = next ();
+ if (! (t->type == tok_identifier && t->content == "function"))
+ throw parse_error ("expected 'function'");
+
functiondecl *fd = new functiondecl ();
- const token* t = next ();
+ t = next ();
if (! (t->type == tok_identifier))
throw parse_error ("expected identifier");
fd->name = t->content;
@@ -675,11 +703,6 @@ parser::parse_expression ()
return parse_assignment ();
}
-// XXX: in all subsequent calls to parse_expression(),
-// check whether operator priority / associativity
-// suggests that a different expression subtype parser
-// should be called instead
-
expression*
parser::parse_assignment ()
@@ -687,10 +710,10 @@ parser::parse_assignment ()
expression* op1 = parse_ternary ();
const token* t = peek ();
- // left-associative operators
- while (t && t->type == tok_operator
+ // right-associative operators
+ if (t && t->type == tok_operator
&& (t->content == "=" ||
- t->content == "<<" ||
+ t->content == "<<<" ||
t->content == "+=" ||
false)) // XXX: add /= etc.
{
@@ -701,9 +724,10 @@ parser::parse_assignment ()
e->op = t->content;
e->tok = t;
next ();
- e->right = parse_ternary ();
+ e->right = parse_expression ();
op1 = e;
- t = peek ();
+ // XXX: map assign/accumlate operators like +=, /=
+ // to ordinary assignment + nested binary_expression
}
return op1;
@@ -1056,17 +1080,24 @@ parser::parse_symbol ()
struct functioncall* f = new functioncall;
f->tok = t2;
f->function = name;
+ // Allow empty actual parameter list
+ const token* t3 = peek ();
+ if (t3 && t3->type == tok_operator && t3->content == ")")
+ {
+ next ();
+ return f;
+ }
while (1)
- {
- f->args.push_back (parse_expression ());
- t = next ();
- if (t->type == tok_operator && t->content == ")")
- break;
- if (t->type == tok_operator && t->content == ",")
- continue;
- else
- throw parse_error ("expected ',' or ')'");
- }
+ {
+ f->args.push_back (parse_expression ());
+ t = next ();
+ if (t->type == tok_operator && t->content == ")")
+ break;
+ if (t->type == tok_operator && t->content == ",")
+ continue;
+ else
+ throw parse_error ("expected ',' or ')'");
+ }
return f;
}
else