# HG changeset patch # User Michael Goffioul # Date 1393116977 18000 # Node ID 932aca9a7c57140511065ecc9afcd561c8a5109c # Parent e1b9c8277ada41625cd29393ce0ae4df63128968 Allow multi-level classdef package. * lex.h (octave_base_lexer::fq_identifier_contains_keyword, octave_base_lexer::handle_fq_identifier, octave_base_lexer::enable_fq_identifier): New methods. * lex.ll (octave_base_lexer::fq_identifier_contains_keyword, octave_base_lexer::handle_fq_identifier, octave_base_lexer::enable_fq_identifier): Likewise. (FQ_IDENT_START, FQIDENT): New exclusive start condition and regex to handle fully-qualified identifier. (superclass reference rule, metaclass query rule): Use FQIDENT. (octave_base_lexer::handle_superclass_identifier, octave_base_lexer::handle_meta_identifier): Don't split package name. * parse.h (octave_base_parser::make_superclass_ref, octave_base_parser::make_meta_class_query): Remove package_nm argument. * pt-classdef.h (tree_classdef_superclass::id, tree_classdef_superclass::pkg): Removed members, replaced by cls_name. (tree_classdef_superclass::~tree_classdef_superclass): Remove deletion of removed members. (tree_classdef_superclass::cls_name): New member. (tree_classdef_superclass::tree_classdef_superclass): Initialize it. (tree_classdef_superclass::ident, tree_classdef_superclass::package): Removed methods. (tree_classdef_superclass::class_name): New method. * token.h (token::meta_name_token): Remove enum value. (token(int, std::string, std::string, std::string, int, int)): Remove constructor. (token::superclass_package_name, token::meta_package_name, token::meta_class_name): Remove methods. (token::sc::package_nm, token::mc): Remove union members. * token.cc (token(int, std::string, std::string, std::string, int, int)): Remove constructor. (token::~token): Remove case of meta_name_token. (token::superclass_package_name, token::meta_package_name, token::meta_class_name): Remove methods. * oct-parse.in.yy (FQ_IDENT): New terminal. (superclass_identifier): Adapt to changes in class token and class octave_base_parser. (meta_identifier): Likewise. (superclass_list): Add mid-rule to enable fully-qualified identifier. (superclass): Use FQ_IDENT. (octave_base_parser::make_superclass_ref, octave_base_parser::make_meta_class_query): Remove package_nm argument. * ov-classdef.cc (octave_classdef_superclass_ref::do_multi_index_op): Adapt to removal of package_nm argument. (F__meta_class_query__): Likewise. (cdef_class::make_meta_class): Adapt to changes in class tree_classdef_superclass. diff -r e1b9c8277ada -r 932aca9a7c57 libinterp/octave-value/ov-classdef.cc --- a/libinterp/octave-value/ov-classdef.cc Sat Feb 22 08:23:26 2014 -0800 +++ b/libinterp/octave-value/ov-classdef.cc Sat Feb 22 19:56:17 2014 -0500 @@ -1221,12 +1221,9 @@ if (! error_state && ctx.ok ()) { std::string mname = args(0).string_value (); - std::string pname = args(1).string_value (); - std::string cname = args(2).string_value (); - - std::string cls_name = (pname.empty () ? - cname : pname + "." + cname); - cdef_class cls = lookup_class (cls_name); + std::string cname = args(1).string_value (); + + cdef_class cls = lookup_class (cname); if (! error_state) { @@ -1248,7 +1245,7 @@ } else ::error ("`%s' is not a direct superclass of `%s'", - cls_name.c_str (), ctx.get_name ().c_str ()); + cname.c_str (), ctx.get_name ().c_str ()); } else { @@ -1274,11 +1271,11 @@ meth_name); else ::error ("no method `%s' found in superclass `%s'", - meth_name.c_str (), cls_name.c_str ()); + meth_name.c_str (), cname.c_str ()); } else ::error ("`%s' is not a superclass of `%s'", - cls_name.c_str (), ctx.get_name ().c_str ()); + cname.c_str (), ctx.get_name ().c_str ()); } else ::error ("method name mismatch (`%s' != `%s')", @@ -1969,14 +1966,9 @@ if (args(0).string_value () == obj_name) { - std::string package_name = args(1).string_value (); - std::string class_name = args(2).string_value (); - - std::string ctor_name = (package_name.empty () - ? class_name - : package_name + "." + class_name); - - cdef_class cls = lookup_class (ctor_name, false); + std::string class_name = args(1).string_value (); + + cdef_class cls = lookup_class (class_name, false); if (cls.ok ()) ctor_list.push_back (cls); @@ -2702,9 +2694,7 @@ for (tree_classdef_superclass_list::iterator it = t->superclass_list ()->begin (); ! error_state && it != t->superclass_list ()->end (); ++it) { - std::string sclass_name = - ((*it)->package () ? (*it)->package ()->name () + "." : std::string ()) - + (*it)->ident ()->name (); + std::string sclass_name = (*it)->class_name (); gnulib::printf ("superclass: %s\n", sclass_name.c_str ()); @@ -3872,17 +3862,12 @@ octave_value retval; std::cerr << "__meta_class_query__ (" - << args(0).string_value () << ", " - << args(1).string_value () << ")" + << args(0).string_value () << ")" << std::endl; - if (args.length () == 2) + if (args.length () == 1) { - std::string pkg = args(0).string_value (); - std::string cls = args(1).string_value (); - - if (! pkg.empty ()) - cls = pkg + "." + cls; + std::string cls = args(0).string_value (); if (! error_state) retval = to_ov (lookup_class (cls)); diff -r e1b9c8277ada -r 932aca9a7c57 libinterp/parse-tree/lex.h --- a/libinterp/parse-tree/lex.h Sat Feb 22 08:23:26 2014 -0800 +++ b/libinterp/parse-tree/lex.h Sat Feb 22 19:56:17 2014 -0500 @@ -580,6 +580,8 @@ int is_keyword_token (const std::string& s); + bool fq_identifier_contains_keyword (const std::string& s); + bool whitespace_is_significant (void); void handle_number (void); @@ -598,6 +600,8 @@ int handle_meta_identifier (void); + int handle_fq_identifier (void); + int handle_identifier (void); void maybe_warn_separator_insert (char sep); @@ -683,6 +687,8 @@ int show_token (int tok); + void enable_fq_identifier (void); + protected: std::stack start_state_stack; diff -r e1b9c8277ada -r 932aca9a7c57 libinterp/parse-tree/lex.ll --- a/libinterp/parse-tree/lex.ll Sat Feb 22 08:23:26 2014 -0800 +++ b/libinterp/parse-tree/lex.ll Sat Feb 22 19:56:17 2014 -0500 @@ -54,6 +54,8 @@ %x DQ_STRING_START %x SQ_STRING_START +%x FQ_IDENT_START + %{ #include @@ -311,6 +313,7 @@ Im [iIjJ] CCHAR [#%] IDENT ([_$a-zA-Z][_$a-zA-Z0-9]*) +FQIDENT ({IDENT}(\.{IDENT})*) EXPON ([DdEe][+-]?{D}+) NUMBER (({D}+\.?{D}*{EXPON}?)|(\.{D}+{EXPON}?)|(0[xX][0-9a-fA-F]+)) @@ -1031,6 +1034,35 @@ } %{ +// Fully-qualified identifiers (used for classdef). +%} + +{FQIDENT} { + curr_lexer->lexer_debug ("{FQIDENT}"); + curr_lexer->pop_start_state (); + + int id_tok = curr_lexer->handle_fq_identifier (); + + if (id_tok >= 0) + { + curr_lexer->looking_for_object_index = true; + + return curr_lexer->count_token_internal (id_tok); + } + } + +{S}+ { + curr_lexer->current_input_column += yyleng; + + curr_lexer->mark_previous_token_trailing_space (); + } + +. { + yyless (0); + curr_lexer->pop_start_state (); + } + +%{ // Imaginary numbers. %} @@ -1168,9 +1200,8 @@ // Superclass method identifiers. %} -{IDENT}@{IDENT} | -{IDENT}@{IDENT}\.{IDENT} { - curr_lexer->lexer_debug ("{IDENT}@{IDENT}|{IDENT}@{IDENT}\\.{IDENT}"); +{IDENT}@{FQIDENT} { + curr_lexer->lexer_debug ("{IDENT}@{FQIDENT}"); if (curr_lexer->previous_token_may_be_command ()) { @@ -1194,9 +1225,8 @@ // Metaclass query %} -\?{IDENT} | -\?{IDENT}\.{IDENT} { - curr_lexer->lexer_debug ("\\?{IDENT}|\\?{IDENT}\\.{IDENT}"); +\?{FQIDENT} { + curr_lexer->lexer_debug ("\\?{FQIDENT}"); if (curr_lexer->previous_token_may_be_command () && curr_lexer->space_follows_previous_token ()) @@ -2560,6 +2590,34 @@ } bool +octave_base_lexer::fq_identifier_contains_keyword (const std::string& s) +{ + size_t p1 = 0; + size_t p2; + + std::string s_part; + + do + { + p2 = s.find ('.', p1); + + if (p2 != std::string::npos) + { + s_part = s.substr (p1, p2 - p1); + p1 = p2 + 1; + } + else + s_part = s.substr (p1); + + if (is_keyword_token (s_part)) + return true; + } + while (p2 != std::string::npos); + + return false; +} + +bool octave_base_lexer::whitespace_is_significant (void) { return (nesting_level.is_bracket () @@ -2737,23 +2795,16 @@ std::string cls = meth.substr (pos + 1); meth = meth.substr (0, pos); - std::string pkg; - pos = cls.find ("."); - if (pos != std::string::npos) - { - pkg = cls.substr (0, pos); - cls = cls.substr (pos + 1); - } - - int kw_token = (is_keyword_token (meth) || is_keyword_token (cls) - || is_keyword_token (pkg)); + bool kw_token = (is_keyword_token (meth) + || fq_identifier_contains_keyword (cls)); + if (kw_token) { error ("method, class, and package names may not be keywords"); return LEXICAL_ERROR; } - push_token (new token (SUPERCLASSREF, meth, pkg, cls, + push_token (new token (SUPERCLASSREF, meth, cls, input_line_number, current_input_column)); current_input_column += flex_yyleng (); @@ -2766,22 +2817,13 @@ { std::string cls = std::string(flex_yytext ()).substr (1); - std::string pkg; - size_t pos = cls.find ("."); - if (pos != std::string::npos) - { - pkg = cls.substr (0, pos); - cls = cls.substr (pos + 1); - } - - int kw_token = is_keyword_token (cls) || is_keyword_token (pkg); - if (kw_token) + if (fq_identifier_contains_keyword (cls)) { error ("class and package names may not be keywords"); return LEXICAL_ERROR; } - push_token (new token (METAQUERY, pkg, cls, input_line_number, + push_token (new token (METAQUERY, cls, input_line_number, current_input_column)); current_input_column += flex_yyleng (); @@ -2789,6 +2831,25 @@ return METAQUERY; } +int +octave_base_lexer::handle_fq_identifier (void) +{ + std::string tok = flex_yytext (); + + if (fq_identifier_contains_keyword (tok)) + { + error ("function, method, class, and package names may not be keywords"); + return LEXICAL_ERROR; + } + + push_token (new token (FQ_IDENT, tok, input_line_number, + current_input_column)); + + current_input_column += flex_yyleng (); + + return FQ_IDENT; +} + // Figure out exactly what kind of token to return when we have seen // an identifier. Handles keywords. Return -1 if the identifier // should be ignored. @@ -3346,6 +3407,12 @@ return tok; } +void +octave_base_lexer::enable_fq_identifier (void) +{ + push_start_state (FQ_IDENT_START); +} + int octave_lexer::fill_flex_buffer (char *buf, unsigned max_size) { diff -r e1b9c8277ada -r 932aca9a7c57 libinterp/parse-tree/oct-parse.in.yy --- a/libinterp/parse-tree/oct-parse.in.yy Sat Feb 22 08:23:26 2014 -0800 +++ b/libinterp/parse-tree/oct-parse.in.yy Sat Feb 22 19:56:17 2014 -0500 @@ -235,6 +235,7 @@ %token PROPERTIES METHODS EVENTS ENUMERATION %token METAQUERY %token SUPERCLASSREF +%token FQ_IDENT %token GET SET %token FCN @@ -485,23 +486,20 @@ : SUPERCLASSREF { std::string method_nm = $1->superclass_method_name (); - std::string package_nm = $1->superclass_package_name (); std::string class_nm = $1->superclass_class_name (); $$ = parser.make_superclass_ref - (method_nm, package_nm, class_nm, + (method_nm, class_nm, $1->line (), $1->column ()); } ; meta_identifier : METAQUERY { - std::string package_nm = $1->meta_package_name (); - std::string class_nm = $1->meta_class_name (); - - $$ = parser.make_meta_class_query - (package_nm, class_nm, - $1->line (), $1->column ()); + std::string class_nm = $1->text (); + + $$ = parser.make_meta_class_query (class_nm, $1->line (), + $1->column ()); } ; @@ -1553,19 +1551,21 @@ { $$ = $1; } ; -superclass_list : EXPR_LT superclass - { $$ = new tree_classdef_superclass_list ($2); } - | superclass_list EXPR_AND superclass +superclass_list : EXPR_LT + { lexer.enable_fq_identifier (); } + superclass + { $$ = new tree_classdef_superclass_list ($3); } + | superclass_list EXPR_AND + { lexer.enable_fq_identifier (); } + superclass { - $1->append ($3); + $1->append ($4); $$ = $1; } ; -superclass : identifier - { $$ = new tree_classdef_superclass ($1); } - | identifier '.' identifier - { $$ = new tree_classdef_superclass ($3, $1); } +superclass : FQ_IDENT + { $$ = new tree_classdef_superclass ($1->text ()); } ; class_body : properties_block @@ -3115,14 +3115,12 @@ tree_funcall * octave_base_parser::make_superclass_ref (const std::string& method_nm, - const std::string& package_nm, const std::string& class_nm, int l, int c) { octave_value_list args; - args(2) = class_nm; - args(1) = package_nm; + args(1) = class_nm; args(0) = method_nm; octave_value fcn @@ -3132,14 +3130,12 @@ } tree_funcall * -octave_base_parser::make_meta_class_query (const std::string& package_nm, - const std::string& class_nm, +octave_base_parser::make_meta_class_query (const std::string& class_nm, int l, int c) { octave_value_list args; - args(1) = class_nm; - args(0) = package_nm; + args(0) = class_nm; octave_value fcn = symbol_table::find_built_in_function ("__meta_class_query__"); diff -r e1b9c8277ada -r 932aca9a7c57 libinterp/parse-tree/parse.h --- a/libinterp/parse-tree/parse.h Sat Feb 22 08:23:26 2014 -0800 +++ b/libinterp/parse-tree/parse.h Sat Feb 22 19:56:17 2014 -0500 @@ -300,13 +300,11 @@ tree_funcall * make_superclass_ref (const std::string& method_nm, - const std::string& package_nm, const std::string& class_nm, int l, int c); tree_funcall * - make_meta_class_query (const std::string& package_nm, - const std::string& class_nm, + make_meta_class_query (const std::string& class_nm, int l, int c); tree_classdef * diff -r e1b9c8277ada -r 932aca9a7c57 libinterp/parse-tree/pt-classdef.h --- a/libinterp/parse-tree/pt-classdef.h Sat Feb 22 08:23:26 2014 -0800 +++ b/libinterp/parse-tree/pt-classdef.h Sat Feb 22 19:56:17 2014 -0500 @@ -100,25 +100,18 @@ { public: - tree_classdef_superclass (tree_identifier *i = 0, tree_identifier *p = 0) - : id (i), pkg (p) { } + tree_classdef_superclass (const std::string& cname) + : cls_name (cname) { } - ~tree_classdef_superclass (void) - { - delete id; - delete pkg; - } + ~tree_classdef_superclass (void) { } - tree_identifier *ident (void) { return id; } - - tree_identifier * package (void) { return pkg; } + std::string class_name (void) { return cls_name; } void accept (tree_walker&); private: - tree_identifier *id; - tree_identifier *pkg; + std::string cls_name; // No copying! diff -r e1b9c8277ada -r 932aca9a7c57 libinterp/parse-tree/token.cc --- a/libinterp/parse-tree/token.cc Sat Feb 22 08:23:26 2014 -0800 +++ b/libinterp/parse-tree/token.cc Sat Feb 22 19:56:17 2014 -0500 @@ -97,7 +97,7 @@ sr = s; } -token::token (int tv, const std::string& pkg, const std::string& cls, +token::token (int tv, const std::string& mth, const std::string& cls, int l, int c) { maybe_cmd = false; @@ -105,22 +105,8 @@ line_num = l; column_num = c; tok_val = tv; - type_tag = meta_name_token; - mc.package_nm = new std::string (pkg); - mc.class_nm = new std::string (cls); -} - -token::token (int tv, const std::string& mth, const std::string& pkg, - const std::string& cls, int l, int c) -{ - maybe_cmd = false; - tspc = false; - line_num = l; - column_num = c; - tok_val = tv; type_tag = scls_name_token; sc.method_nm = new std::string (mth); - sc.package_nm = new std::string (pkg); sc.class_nm = new std::string (cls); } @@ -132,15 +118,8 @@ if (type_tag == scls_name_token) { delete sc.method_nm; - delete sc.package_nm; delete sc.class_nm; } - - if (type_tag == meta_name_token) - { - delete mc.package_nm; - delete mc.class_nm; - } } std::string @@ -192,13 +171,6 @@ } std::string -token::superclass_package_name (void) -{ - assert (type_tag == scls_name_token); - return *sc.package_nm; -} - -std::string token::superclass_class_name (void) { assert (type_tag == scls_name_token); @@ -206,20 +178,6 @@ } std::string -token::meta_package_name (void) -{ - assert (type_tag == meta_name_token); - return *mc.package_nm; -} - -std::string -token::meta_class_name (void) -{ - assert (type_tag == meta_name_token); - return *mc.class_nm; -} - -std::string token::text_rep (void) { return orig_text; diff -r e1b9c8277ada -r 932aca9a7c57 libinterp/parse-tree/token.h --- a/libinterp/parse-tree/token.h Sat Feb 22 08:23:26 2014 -0800 +++ b/libinterp/parse-tree/token.h Sat Feb 22 19:56:17 2014 -0500 @@ -41,7 +41,6 @@ ettype_token, sym_rec_token, scls_name_token, - meta_name_token }; enum end_tok_type @@ -69,10 +68,8 @@ int l = -1, int c = -1); token (int tv, end_tok_type t, int l = -1, int c = -1); token (int tv, symbol_table::symbol_record *s, int l = -1, int c = -1); - token (int tv, const std::string& pkg, const std::string& cls, + token (int tv, const std::string& mth, const std::string& cls, int l = -1, int c = -1); - token (int tv, const std::string& mth, const std::string& pkg, - const std::string& cls, int l = -1, int c = -1); ~token (void); @@ -106,12 +103,8 @@ symbol_table::symbol_record *sym_rec (void); std::string superclass_method_name (void); - std::string superclass_package_name (void); std::string superclass_class_name (void); - std::string meta_package_name (void); - std::string meta_class_name (void); - std::string text_rep (void); private: @@ -137,14 +130,8 @@ struct { std::string *method_nm; - std::string *package_nm; std::string *class_nm; } sc; - struct - { - std::string *package_nm; - std::string *class_nm; - } mc; }; std::string orig_text; };