diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2010-03-03 00:28:22 -0500 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2010-03-03 00:33:43 -0500 |
commit | f4fe2e932cc8f445e9e1bc52863e11b669e3afc9 (patch) | |
tree | ba062952c0a37f02ebcf0eb2f533d44ee41fdb25 /parse.cxx | |
parent | d105f6642677bd9ef1b20d1ba180ba0163cb0fa6 (diff) | |
download | systemtap-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.cxx | 42 |
1 files changed, 40 insertions, 2 deletions
@@ -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") |