summaryrefslogtreecommitdiffstats
path: root/parse.cxx
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@elastic.org>2010-03-03 00:28:22 -0500
committerFrank Ch. Eigler <fche@elastic.org>2010-03-03 00:33:43 -0500
commitf4fe2e932cc8f445e9e1bc52863e11b669e3afc9 (patch)
treeba062952c0a37f02ebcf0eb2f533d44ee41fdb25 /parse.cxx
parentd105f6642677bd9ef1b20d1ba180ba0163cb0fa6 (diff)
downloadsystemtap-steved-f4fe2e932cc8f445e9e1bc52863e11b669e3afc9.tar.gz
systemtap-steved-f4fe2e932cc8f445e9e1bc52863e11b669e3afc9.tar.xz
systemtap-steved-f4fe2e932cc8f445e9e1bc52863e11b669e3afc9.zip
PR11004: try / catch error-handling script syntax
* parse.h (try_block): New class. Update basic visitors. * staptree.cxx: Implement basic visitors. * parse.cxx (expect_kw): Fix to actually look for keywords. (parse_try_block): New function. (lexer ctor): Designate 'try' and 'catch' as keywords. * elaborate.cxx (dead_assignment_remover, dead_statmtexpr_remover): Optimize. (other visitors): Implement. * translate.cxx (c_unparser): Implement via super-handy __local__ labels. (emit_probe, emit_function): Make outer out: label also __local__. * testsuite/buildok/fortyone.stp, semko/fortynine.stp, systemtap.base/trycatch.exp: Test it. * NEWS, doc/langref.txt, stap.1.in: Document it.
Diffstat (limited to 'parse.cxx')
-rw-r--r--parse.cxx42
1 files changed, 40 insertions, 2 deletions
diff --git a/parse.cxx b/parse.cxx
index 9d32a8cb..c517cd1a 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -1,5 +1,5 @@
// recursive descent parser for systemtap scripts
-// Copyright (C) 2005-2009 Red Hat Inc.
+// Copyright (C) 2005-2010 Red Hat Inc.
// Copyright (C) 2006 Intel Corporation.
// Copyright (C) 2007 Bull S.A.S
//
@@ -606,7 +606,7 @@ parser::expect_op (std::string const & expected)
const token*
parser::expect_kw (std::string const & expected)
{
- return expect_known (tok_identifier, expected);
+ return expect_known (tok_keyword, expected);
}
const token*
@@ -703,6 +703,8 @@ lexer::lexer (istream& input, const string& in, systemtap_session& s):
keywords.insert("next");
keywords.insert("string");
keywords.insert("long");
+ keywords.insert("try");
+ keywords.insert("catch");
}
}
@@ -1283,6 +1285,40 @@ parser::parse_stmt_block ()
}
+try_block*
+parser::parse_try_block ()
+{
+ try_block* pb = new try_block;
+
+ pb->tok = expect_kw ("try");
+ pb->try_block = parse_stmt_block();
+ expect_kw ("catch");
+
+ const token* t = peek ();
+ if (t->type == tok_operator && t->content == "(")
+ {
+ next (); // swallow the '('
+
+ t = next();
+ if (! (t->type == tok_identifier))
+ throw parse_error ("expected identifier");
+ symbol* sym = new symbol;
+ sym->tok = t;
+ sym->name = t->content;
+ pb->catch_error_var = sym;
+
+ expect_op (")");
+ }
+ else
+ pb->catch_error_var = 0;
+
+ pb->catch_block = parse_stmt_block();
+
+ return pb;
+}
+
+
+
statement*
parser::parse_statement ()
{
@@ -1292,6 +1328,8 @@ parser::parse_statement ()
return new null_statement (next ());
else if (t && t->type == tok_operator && t->content == "{")
return parse_stmt_block (); // Don't squash semicolons.
+ else if (t && t->type == tok_keyword && t->content == "try")
+ return parse_try_block (); // Don't squash semicolons.
else if (t && t->type == tok_keyword && t->content == "if")
return parse_if_statement (); // Don't squash semicolons.
else if (t && t->type == tok_keyword && t->content == "for")