diff options
author | fche <fche> | 2005-05-30 21:28:44 +0000 |
---|---|---|
committer | fche <fche> | 2005-05-30 21:28:44 +0000 |
commit | ce10591c2048cc3c5e4979b15e14fecc2a384968 (patch) | |
tree | 09b4a09692e1810809091ad474e35e0b3f752a81 /parse.cxx | |
parent | 4383d78cedb616af407f35c996c4eff808704ea6 (diff) | |
download | systemtap-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.cxx | 68 |
1 files changed, 51 insertions, 17 deletions
@@ -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; -} |