From 0054a7eaacba2a7183be67b28e7746ed55a8f6d1 Mon Sep 17 00:00:00 2001 From: fche Date: Thu, 3 Mar 2005 21:24:24 +0000 Subject: [PATCH] 2005-03-03 Frank Ch. Eigler * parse.cxx (parse_assignment): Assert lvalueness of left operand. * staptree.h (expression): Add is_lvalue member. * staptree.cxx (functioncall::resolve_types): Don't crash on formal-vs-actual argument count mismatch. (*): Add some is_lvalue stub functions. * testsuite/*: Some new tests. --- ChangeLog | 10 ++++++++++ README | 10 ++++++---- parse.cxx | 2 ++ staptree.cxx | 28 +++++++++++++++++++++++++++- staptree.h | 12 +++++++++++- testsuite/parseko/three.stp | 5 +++++ testsuite/semko/eight.stp | 5 +++++ testsuite/semko/five.stp | 10 ++++++++++ testsuite/semko/seven.stp | 6 ++++++ testsuite/semko/six.stp | 6 ++++++ testsuite/semok/five.stp | 7 +++++++ 11 files changed, 95 insertions(+), 6 deletions(-) create mode 100755 testsuite/parseko/three.stp create mode 100755 testsuite/semko/eight.stp create mode 100755 testsuite/semko/five.stp create mode 100755 testsuite/semko/seven.stp create mode 100755 testsuite/semko/six.stp create mode 100755 testsuite/semok/five.stp diff --git a/ChangeLog b/ChangeLog index cbc73eb75..a03c482bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2005-03-03 Frank Ch. Eigler + + * parse.cxx (parse_assignment): Assert lvalueness of left + operand. + * staptree.h (expression): Add is_lvalue member. + * staptree.cxx (functioncall::resolve_types): Don't crash on + formal-vs-actual argument count mismatch. + (*): Add some is_lvalue stub functions. + * testsuite/*: Some new tests. + 2005-03-01 Frank Ch. Eigler * parse.cxx: Implement left-associativity for several types of diff --git a/README b/README index 6eff13fe6..1bf982b05 100644 --- a/README +++ b/README @@ -1,10 +1,12 @@ -systemtap prototype #3 +systemtap prototype #3.1 - demonstrates partial parsing of hypothetical systemtap script language using hand-written simpe LL(1) recursive-descent parser and similar little lexer: parse.cxx, parse.h -- baby grammar examples under testsuite/parseok -- only "probe" top-level construct is parsed; "global" missing; +- semantic analysis in stapfile.cxx, driven from semtest.cxx +- examples under testsuite +- "probe", "global", "function" top-level constructs parsed no provider-oriented syntax provided yet - use autotools-style configure; make; make check -- to see parse tree dump, use stdin: echo 'SCRIPT FRAGMENT' | ./stap +- to see parse tree dump, use stdin: echo 'SCRIPT FRAGMENT' | ./parsetest +- to see type inference results, use stdin: echo 'SCRIPT FRAGMENT' | ./semtest diff --git a/parse.cxx b/parse.cxx index 4238f37e7..41ec6fef9 100644 --- a/parse.cxx +++ b/parse.cxx @@ -648,6 +648,8 @@ parser::parse_assignment () t->content == "+=" || false)) // XXX: add /= etc. { + if (op1->is_lvalue () == 0) + throw parse_error ("assignment not to lvalue"); assignment* e = new assignment; e->left = op1; e->op = t->content; diff --git a/staptree.cxx b/staptree.cxx index 34a1d0d34..8a4fc1483 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -753,7 +753,7 @@ functioncall::resolve_types (typeresolution_info& r, exp_type t) // now resolve the function parameters if (args.size() != referent->formal_args.size()) r.unresolved (tok); - for (unsigned i=0; iformal_args[i]->type; @@ -901,3 +901,29 @@ typeresolution_info::resolved (const token* tok, exp_type t) num_newly_resolved ++; // cerr << "resolved " << *tok << " type " << t << endl; } + + +// ------------------------------------------------------------------------ +// semantic processing: lvalue checking + +bool +pre_crement::is_lvalue () +{ + return operand->is_lvalue (); +} + + +bool +post_crement::is_lvalue () +{ + return operand->is_lvalue (); +} + + +bool +assignment::is_lvalue () +{ + return left->is_lvalue (); +} + + diff --git a/staptree.h b/staptree.h index 80bffa7e6..a95d9f057 100644 --- a/staptree.h +++ b/staptree.h @@ -32,6 +32,7 @@ struct expression virtual ~expression (); virtual void resolve_symbols (symresolution_info& r) = 0; virtual void resolve_types (typeresolution_info& r, exp_type t) = 0; + virtual bool is_lvalue () = 0; }; ostream& operator << (ostream& o, expression& k); @@ -41,6 +42,7 @@ struct literal: public expression { void resolve_symbols (symresolution_info& r); void resolve_types (typeresolution_info& r, exp_type t); + bool is_lvalue () { return false; } }; @@ -68,6 +70,7 @@ struct binary_expression: public expression void print (ostream& o); void resolve_symbols (symresolution_info& r); void resolve_types (typeresolution_info& r, exp_type t); + bool is_lvalue () { return false; } }; @@ -78,16 +81,19 @@ struct unary_expression: public expression void print (ostream& o); void resolve_symbols (symresolution_info& r); void resolve_types (typeresolution_info& r, exp_type t); + bool is_lvalue () { return false; } }; struct pre_crement: public unary_expression { + bool is_lvalue (); }; struct post_crement: public unary_expression { + bool is_lvalue (); void print (ostream& o); }; @@ -130,11 +136,13 @@ struct ternary_expression: public expression void print (ostream& o); void resolve_symbols (symresolution_info& r); void resolve_types (typeresolution_info& r, exp_type t); + bool is_lvalue () { return false; } }; struct assignment: public binary_expression { + bool is_lvalue (); }; @@ -147,6 +155,7 @@ struct symbol: public expression void print (ostream& o); void resolve_symbols (symresolution_info& r); void resolve_types (typeresolution_info& r, exp_type t); + bool is_lvalue () { return true; } }; @@ -159,10 +168,10 @@ struct arrayindex: public expression void print (ostream& o); void resolve_symbols (symresolution_info& r); void resolve_types (typeresolution_info& r, exp_type t); + bool is_lvalue () { return true; } }; - class functiondecl; struct functioncall: public expression { @@ -173,6 +182,7 @@ struct functioncall: public expression void print (ostream& o); void resolve_symbols (symresolution_info& r); void resolve_types (typeresolution_info& r, exp_type t); + bool is_lvalue () { return false; } }; diff --git a/testsuite/parseko/three.stp b/testsuite/parseko/three.stp new file mode 100755 index 000000000..4db7dd3f4 --- /dev/null +++ b/testsuite/parseko/three.stp @@ -0,0 +1,5 @@ +#! semtest + +probe foo { + 1 + 2 = 3; # bad lvalue +} diff --git a/testsuite/semko/eight.stp b/testsuite/semko/eight.stp new file mode 100755 index 000000000..1bcb344a3 --- /dev/null +++ b/testsuite/semko/eight.stp @@ -0,0 +1,5 @@ +#! semtest + +probe foo { + stats << "string" # stats only collect numbers +} diff --git a/testsuite/semko/five.stp b/testsuite/semko/five.stp new file mode 100755 index 000000000..6887fcede --- /dev/null +++ b/testsuite/semko/five.stp @@ -0,0 +1,10 @@ +#! semtest + +function bar () +{ + return 0 +} + +probe foo { + bar (1, 2) # arg count mismatch +} diff --git a/testsuite/semko/seven.stp b/testsuite/semko/seven.stp new file mode 100755 index 000000000..7d987f77b --- /dev/null +++ b/testsuite/semko/seven.stp @@ -0,0 +1,6 @@ +#! semtest + +probe foo { + baz[1] = 4; + baz["1"] = 5; # inconsistent index types +} diff --git a/testsuite/semko/six.stp b/testsuite/semko/six.stp new file mode 100755 index 000000000..aa7d10d70 --- /dev/null +++ b/testsuite/semko/six.stp @@ -0,0 +1,6 @@ +#! semtest + +probe foo { + bar[1] = 2; + bar[1, 2] = 3; # inconsistent array dimensions +} diff --git a/testsuite/semok/five.stp b/testsuite/semok/five.stp new file mode 100755 index 000000000..c8b59e734 --- /dev/null +++ b/testsuite/semok/five.stp @@ -0,0 +1,7 @@ +#! parsetest + +probe foo +{ + array[1] = array[2] = 3; + statvar << value << 4; +} -- 2.43.5