Mercurial > hg > octave-nkf
comparison libinterp/parse-tree/lex.ll @ 18588:932aca9a7c57
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.
author | Michael Goffioul <michael.goffioul@gmail.com> |
---|---|
date | Sat, 22 Feb 2014 19:56:17 -0500 |
parents | 4e0d72145c5a |
children | f958e8cd6348 |
comparison
equal
deleted
inserted
replaced
18585:e1b9c8277ada | 18588:932aca9a7c57 |
---|---|
51 %x BLOCK_COMMENT_START | 51 %x BLOCK_COMMENT_START |
52 %x LINE_COMMENT_START | 52 %x LINE_COMMENT_START |
53 | 53 |
54 %x DQ_STRING_START | 54 %x DQ_STRING_START |
55 %x SQ_STRING_START | 55 %x SQ_STRING_START |
56 | |
57 %x FQ_IDENT_START | |
56 | 58 |
57 %{ | 59 %{ |
58 | 60 |
59 #include <cctype> | 61 #include <cctype> |
60 #include <cstring> | 62 #include <cstring> |
309 S [ \t] | 311 S [ \t] |
310 NL ((\n)|(\r)|(\r\n)) | 312 NL ((\n)|(\r)|(\r\n)) |
311 Im [iIjJ] | 313 Im [iIjJ] |
312 CCHAR [#%] | 314 CCHAR [#%] |
313 IDENT ([_$a-zA-Z][_$a-zA-Z0-9]*) | 315 IDENT ([_$a-zA-Z][_$a-zA-Z0-9]*) |
316 FQIDENT ({IDENT}(\.{IDENT})*) | |
314 EXPON ([DdEe][+-]?{D}+) | 317 EXPON ([DdEe][+-]?{D}+) |
315 NUMBER (({D}+\.?{D}*{EXPON}?)|(\.{D}+{EXPON}?)|(0[xX][0-9a-fA-F]+)) | 318 NUMBER (({D}+\.?{D}*{EXPON}?)|(\.{D}+{EXPON}?)|(0[xX][0-9a-fA-F]+)) |
316 | 319 |
317 ANY_EXCEPT_NL [^\r\n] | 320 ANY_EXCEPT_NL [^\r\n] |
318 ANY_INCLUDING_NL (.|{NL}) | 321 ANY_INCLUDING_NL (.|{NL}) |
1026 curr_lexer->current_input_column = 1; | 1029 curr_lexer->current_input_column = 1; |
1027 | 1030 |
1028 error ("unterminated character string constant"); | 1031 error ("unterminated character string constant"); |
1029 | 1032 |
1030 return LEXICAL_ERROR; | 1033 return LEXICAL_ERROR; |
1034 } | |
1035 | |
1036 %{ | |
1037 // Fully-qualified identifiers (used for classdef). | |
1038 %} | |
1039 | |
1040 <FQ_IDENT_START>{FQIDENT} { | |
1041 curr_lexer->lexer_debug ("<FQ_IDENT_START>{FQIDENT}"); | |
1042 curr_lexer->pop_start_state (); | |
1043 | |
1044 int id_tok = curr_lexer->handle_fq_identifier (); | |
1045 | |
1046 if (id_tok >= 0) | |
1047 { | |
1048 curr_lexer->looking_for_object_index = true; | |
1049 | |
1050 return curr_lexer->count_token_internal (id_tok); | |
1051 } | |
1052 } | |
1053 | |
1054 <FQ_IDENT_START>{S}+ { | |
1055 curr_lexer->current_input_column += yyleng; | |
1056 | |
1057 curr_lexer->mark_previous_token_trailing_space (); | |
1058 } | |
1059 | |
1060 <FQ_IDENT_START>. { | |
1061 yyless (0); | |
1062 curr_lexer->pop_start_state (); | |
1031 } | 1063 } |
1032 | 1064 |
1033 %{ | 1065 %{ |
1034 // Imaginary numbers. | 1066 // Imaginary numbers. |
1035 %} | 1067 %} |
1166 | 1198 |
1167 %{ | 1199 %{ |
1168 // Superclass method identifiers. | 1200 // Superclass method identifiers. |
1169 %} | 1201 %} |
1170 | 1202 |
1171 {IDENT}@{IDENT} | | 1203 {IDENT}@{FQIDENT} { |
1172 {IDENT}@{IDENT}\.{IDENT} { | 1204 curr_lexer->lexer_debug ("{IDENT}@{FQIDENT}"); |
1173 curr_lexer->lexer_debug ("{IDENT}@{IDENT}|{IDENT}@{IDENT}\\.{IDENT}"); | |
1174 | 1205 |
1175 if (curr_lexer->previous_token_may_be_command ()) | 1206 if (curr_lexer->previous_token_may_be_command ()) |
1176 { | 1207 { |
1177 yyless (0); | 1208 yyless (0); |
1178 curr_lexer->push_start_state (COMMAND_START); | 1209 curr_lexer->push_start_state (COMMAND_START); |
1192 | 1223 |
1193 %{ | 1224 %{ |
1194 // Metaclass query | 1225 // Metaclass query |
1195 %} | 1226 %} |
1196 | 1227 |
1197 \?{IDENT} | | 1228 \?{FQIDENT} { |
1198 \?{IDENT}\.{IDENT} { | 1229 curr_lexer->lexer_debug ("\\?{FQIDENT}"); |
1199 curr_lexer->lexer_debug ("\\?{IDENT}|\\?{IDENT}\\.{IDENT}"); | |
1200 | 1230 |
1201 if (curr_lexer->previous_token_may_be_command () | 1231 if (curr_lexer->previous_token_may_be_command () |
1202 && curr_lexer->space_follows_previous_token ()) | 1232 && curr_lexer->space_follows_previous_token ()) |
1203 { | 1233 { |
1204 yyless (0); | 1234 yyless (0); |
2558 | 2588 |
2559 return 0; | 2589 return 0; |
2560 } | 2590 } |
2561 | 2591 |
2562 bool | 2592 bool |
2593 octave_base_lexer::fq_identifier_contains_keyword (const std::string& s) | |
2594 { | |
2595 size_t p1 = 0; | |
2596 size_t p2; | |
2597 | |
2598 std::string s_part; | |
2599 | |
2600 do | |
2601 { | |
2602 p2 = s.find ('.', p1); | |
2603 | |
2604 if (p2 != std::string::npos) | |
2605 { | |
2606 s_part = s.substr (p1, p2 - p1); | |
2607 p1 = p2 + 1; | |
2608 } | |
2609 else | |
2610 s_part = s.substr (p1); | |
2611 | |
2612 if (is_keyword_token (s_part)) | |
2613 return true; | |
2614 } | |
2615 while (p2 != std::string::npos); | |
2616 | |
2617 return false; | |
2618 } | |
2619 | |
2620 bool | |
2563 octave_base_lexer::whitespace_is_significant (void) | 2621 octave_base_lexer::whitespace_is_significant (void) |
2564 { | 2622 { |
2565 return (nesting_level.is_bracket () | 2623 return (nesting_level.is_bracket () |
2566 || (nesting_level.is_brace () | 2624 || (nesting_level.is_brace () |
2567 && ! looking_at_object_index.front ())); | 2625 && ! looking_at_object_index.front ())); |
2735 | 2793 |
2736 size_t pos = meth.find ("@"); | 2794 size_t pos = meth.find ("@"); |
2737 std::string cls = meth.substr (pos + 1); | 2795 std::string cls = meth.substr (pos + 1); |
2738 meth = meth.substr (0, pos); | 2796 meth = meth.substr (0, pos); |
2739 | 2797 |
2740 std::string pkg; | 2798 bool kw_token = (is_keyword_token (meth) |
2741 pos = cls.find ("."); | 2799 || fq_identifier_contains_keyword (cls)); |
2742 if (pos != std::string::npos) | 2800 |
2743 { | |
2744 pkg = cls.substr (0, pos); | |
2745 cls = cls.substr (pos + 1); | |
2746 } | |
2747 | |
2748 int kw_token = (is_keyword_token (meth) || is_keyword_token (cls) | |
2749 || is_keyword_token (pkg)); | |
2750 if (kw_token) | 2801 if (kw_token) |
2751 { | 2802 { |
2752 error ("method, class, and package names may not be keywords"); | 2803 error ("method, class, and package names may not be keywords"); |
2753 return LEXICAL_ERROR; | 2804 return LEXICAL_ERROR; |
2754 } | 2805 } |
2755 | 2806 |
2756 push_token (new token (SUPERCLASSREF, meth, pkg, cls, | 2807 push_token (new token (SUPERCLASSREF, meth, cls, |
2757 input_line_number, current_input_column)); | 2808 input_line_number, current_input_column)); |
2758 | 2809 |
2759 current_input_column += flex_yyleng (); | 2810 current_input_column += flex_yyleng (); |
2760 | 2811 |
2761 return SUPERCLASSREF; | 2812 return SUPERCLASSREF; |
2764 int | 2815 int |
2765 octave_base_lexer::handle_meta_identifier (void) | 2816 octave_base_lexer::handle_meta_identifier (void) |
2766 { | 2817 { |
2767 std::string cls = std::string(flex_yytext ()).substr (1); | 2818 std::string cls = std::string(flex_yytext ()).substr (1); |
2768 | 2819 |
2769 std::string pkg; | 2820 if (fq_identifier_contains_keyword (cls)) |
2770 size_t pos = cls.find ("."); | |
2771 if (pos != std::string::npos) | |
2772 { | |
2773 pkg = cls.substr (0, pos); | |
2774 cls = cls.substr (pos + 1); | |
2775 } | |
2776 | |
2777 int kw_token = is_keyword_token (cls) || is_keyword_token (pkg); | |
2778 if (kw_token) | |
2779 { | 2821 { |
2780 error ("class and package names may not be keywords"); | 2822 error ("class and package names may not be keywords"); |
2781 return LEXICAL_ERROR; | 2823 return LEXICAL_ERROR; |
2782 } | 2824 } |
2783 | 2825 |
2784 push_token (new token (METAQUERY, pkg, cls, input_line_number, | 2826 push_token (new token (METAQUERY, cls, input_line_number, |
2785 current_input_column)); | 2827 current_input_column)); |
2786 | 2828 |
2787 current_input_column += flex_yyleng (); | 2829 current_input_column += flex_yyleng (); |
2788 | 2830 |
2789 return METAQUERY; | 2831 return METAQUERY; |
2832 } | |
2833 | |
2834 int | |
2835 octave_base_lexer::handle_fq_identifier (void) | |
2836 { | |
2837 std::string tok = flex_yytext (); | |
2838 | |
2839 if (fq_identifier_contains_keyword (tok)) | |
2840 { | |
2841 error ("function, method, class, and package names may not be keywords"); | |
2842 return LEXICAL_ERROR; | |
2843 } | |
2844 | |
2845 push_token (new token (FQ_IDENT, tok, input_line_number, | |
2846 current_input_column)); | |
2847 | |
2848 current_input_column += flex_yyleng (); | |
2849 | |
2850 return FQ_IDENT; | |
2790 } | 2851 } |
2791 | 2852 |
2792 // Figure out exactly what kind of token to return when we have seen | 2853 // Figure out exactly what kind of token to return when we have seen |
2793 // an identifier. Handles keywords. Return -1 if the identifier | 2854 // an identifier. Handles keywords. Return -1 if the identifier |
2794 // should be ignored. | 2855 // should be ignored. |
3344 } | 3405 } |
3345 | 3406 |
3346 return tok; | 3407 return tok; |
3347 } | 3408 } |
3348 | 3409 |
3410 void | |
3411 octave_base_lexer::enable_fq_identifier (void) | |
3412 { | |
3413 push_start_state (FQ_IDENT_START); | |
3414 } | |
3415 | |
3349 int | 3416 int |
3350 octave_lexer::fill_flex_buffer (char *buf, unsigned max_size) | 3417 octave_lexer::fill_flex_buffer (char *buf, unsigned max_size) |
3351 { | 3418 { |
3352 int status = 0; | 3419 int status = 0; |
3353 | 3420 |