summaryrefslogtreecommitdiffstats
path: root/parse.cxx
diff options
context:
space:
mode:
authorfche <fche>2005-05-30 21:28:44 +0000
committerfche <fche>2005-05-30 21:28:44 +0000
commitce10591c2048cc3c5e4979b15e14fecc2a384968 (patch)
tree09b4a09692e1810809091ad474e35e0b3f752a81 /parse.cxx
parent4383d78cedb616af407f35c996c4eff808704ea6 (diff)
downloadsystemtap-steved-ce10591c2048cc3c5e4979b15e14fecc2a384968.tar.gz
systemtap-steved-ce10591c2048cc3c5e4979b15e14fecc2a384968.tar.xz
systemtap-steved-ce10591c2048cc3c5e4979b15e14fecc2a384968.zip
2005-05-30 Frank Ch. Eigler <fche@redhat.com>
More fully parse & elaborate "expr in array" construct. * staptree.h (array_in): Make this unary. Update .cxx to match. * parse.cxx (parse_array_in): Rewrite. (parse_symbol_plain): Removed. Update .h to match. * elaborate.cxx (typeresolution_info::visit_array_in): New function. (find_array): Tentatively, accept arity=0. * translate.cxx (c_unparser::c_assign): New functions to eliminate much ugly duplication. Use throughout. (visit_symbol): Correct function formal argument search. (c_tmpcounter*::visit): Add missing recursion in several functions. * testsuite/*: Add new tests for array-in construct. Add the first "transok" test. * Makefile.am: Add transok tests. * Makefile.in: Regenerated.
Diffstat (limited to 'parse.cxx')
-rw-r--r--parse.cxx68
1 files changed, 51 insertions, 17 deletions
diff --git a/parse.cxx b/parse.cxx
index 2bf0f977..5f3d6971 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -830,21 +830,67 @@ parser::parse_logical_and ()
expression*
parser::parse_array_in ()
{
- expression* op1 = parse_comparison ();
+ // This is a very tricky case. All these are legit expressions:
+ // "a in b" "a+0 in b" "(a,b) in c" "(c,(d+0)) in b"
+ vector<expression*> indexes;
+ bool parenthesized = false;
const token* t = peek ();
+ if (t && t->type == tok_operator && t->content == "(")
+ {
+ next ();
+ parenthesized = true;
+ }
+
+ while (1)
+ {
+ expression* op1 = parse_comparison ();
+ indexes.push_back (op1);
+
+ if (parenthesized)
+ {
+ const token* t = peek ();
+ if (t && t->type == tok_operator && t->content == ",")
+ {
+ next ();
+ continue;
+ }
+ else if (t && t->type == tok_operator && t->content == ")")
+ {
+ next ();
+ break;
+ }
+ else
+ throw parse_error ("expected ',' or ')'");
+ }
+ else
+ break; // expecting only one expression
+ }
+
+ t = peek ();
if (t && t->type == tok_identifier && t->content == "in")
{
array_in *e = new array_in;
- e->left = op1;
e->op = t->content;
e->tok = t;
- next ();
- e->right = parse_symbol_plain ();
+ next (); // swallow "in"
+
+ arrayindex* a = new arrayindex;
+ a->indexes = indexes;
+
+ t = next ();
+ if (t->type != tok_identifier)
+ throw parse_error ("expected identifier");
+ a->tok = t;
+ a->base = t->content;
+
+ e->operand = a;
return e;
}
+ else if (indexes.size() == 1) // no "in" - need one expression only
+ return indexes[0];
else
- return op1;
+ throw parse_error ("unexpected comma-separated expression list");
}
@@ -1132,15 +1178,3 @@ parser::parse_symbol ()
}
}
-
-symbol*
-parser::parse_symbol_plain () // var only
-{
- symbol *s = new symbol;
- const token* t = next ();
- if (t->type != tok_identifier)
- throw parse_error ("expected identifier");
- s->name = t->content;
- s->tok = t;
- return s;
-}