comparison libinterp/parse-tree/lex.ll @ 16293:57e87ddfee14

create base class for lexer * lex.h, lex.ll, parse.h, oct-parse.in.yy: (octave_base_lexer): New base class for lexer class. Move most of previous octave_lexer class here. Change all uses.
author John W. Eaton <jwe@octave.org>
date Wed, 13 Mar 2013 02:46:56 -0400
parents 6ce905b89cee
children 0925d1f6875e
comparison
equal deleted inserted replaced
16292:6ce905b89cee 16293:57e87ddfee14
109 && defined (YY_FLEX_MAJOR_VERSION) && YY_FLEX_MAJOR_VERSION >= 2 \ 109 && defined (YY_FLEX_MAJOR_VERSION) && YY_FLEX_MAJOR_VERSION >= 2 \
110 && defined (YY_FLEX_MINOR_VERSION) && YY_FLEX_MINOR_VERSION >= 5) 110 && defined (YY_FLEX_MINOR_VERSION) && YY_FLEX_MINOR_VERSION >= 5)
111 #error lex.l requires flex version 2.5.4 or later 111 #error lex.l requires flex version 2.5.4 or later
112 #endif 112 #endif
113 113
114 #define YY_EXTRA_TYPE octave_lexer * 114 #define YY_EXTRA_TYPE octave_base_lexer *
115 #define curr_lexer yyextra 115 #define curr_lexer yyextra
116 116
117 // Arrange to get input via readline. 117 // Arrange to get input via readline.
118 118
119 #ifdef YY_INPUT 119 #ifdef YY_INPUT
120 #undef YY_INPUT 120 #undef YY_INPUT
121 #endif 121 #endif
122 #define YY_INPUT(buf, result, max_size) \ 122 #define YY_INPUT(buf, result, max_size) \
123 result = curr_lexer->read (buf, max_size) 123 result = curr_lexer->fill_flex_buffer (buf, max_size)
124 124
125 // Try to avoid crashing out completely on fatal scanner errors. 125 // Try to avoid crashing out completely on fatal scanner errors.
126 126
127 #ifdef YY_FATAL_ERROR 127 #ifdef YY_FATAL_ERROR
128 #undef YY_FATAL_ERROR 128 #undef YY_FATAL_ERROR
1545 1545
1546 return retval; 1546 return retval;
1547 } 1547 }
1548 1548
1549 void 1549 void
1550 octave_lexer::input_buffer::fill (const std::string& input, bool eof_arg) 1550 octave_base_lexer::input_buffer::fill (const std::string& input, bool eof_arg)
1551 { 1551 {
1552 buffer = input; 1552 buffer = input;
1553 chars_left = buffer.length (); 1553 chars_left = buffer.length ();
1554 pos = buffer.c_str (); 1554 pos = buffer.c_str ();
1555 eof = eof_arg; 1555 eof = eof_arg;
1556 } 1556 }
1557 1557
1558 int 1558 int
1559 octave_lexer::input_buffer::copy_chunk (char *buf, size_t max_size) 1559 octave_base_lexer::input_buffer::copy_chunk (char *buf, size_t max_size)
1560 { 1560 {
1561 static const char * const eol = "\n"; 1561 static const char * const eol = "\n";
1562 1562
1563 size_t len = max_size > chars_left ? chars_left : max_size; 1563 size_t len = max_size > chars_left ? chars_left : max_size;
1564 assert (len > 0); 1564 assert (len > 0);
1579 } 1579 }
1580 else 1580 else
1581 { 1581 {
1582 // There isn't enough room to plug the newline character 1582 // There isn't enough room to plug the newline character
1583 // in the buffer so arrange to have it returned on the next 1583 // in the buffer so arrange to have it returned on the next
1584 // call to octave_lexer::read. 1584 // call to octave_base_lexer::read.
1585 pos = eol; 1585 pos = eol;
1586 chars_left = 1; 1586 chars_left = 1;
1587 } 1587 }
1588 } 1588 }
1589 1589
1590 return len; 1590 return len;
1591 } 1591 }
1592 1592
1593 octave_lexer::~octave_lexer (void) 1593 octave_base_lexer::~octave_base_lexer (void)
1594 { 1594 {
1595 yylex_destroy (scanner); 1595 yylex_destroy (scanner);
1596 } 1596 }
1597 1597
1598 void 1598 void
1599 octave_lexer::init (void) 1599 octave_base_lexer::init (void)
1600 { 1600 {
1601 yylex_init (&scanner); 1601 yylex_init (&scanner);
1602 1602
1603 // Make octave_lexer object available through yyextra in 1603 // Make octave_base_lexer object available through yyextra in
1604 // flex-generated lexer. 1604 // flex-generated lexer.
1605 yyset_extra (this, scanner); 1605 yyset_extra (this, scanner);
1606 1606
1607 clear_start_state (); 1607 clear_start_state ();
1608 } 1608 }
1609 1609
1610 // Inside Flex-generated functions, yyg is the scanner cast to its real 1610 // Inside Flex-generated functions, yyg is the scanner cast to its real
1611 // type. Some flex macros that we use in octave_lexer member functions 1611 // type. Some flex macros that we use in octave_base_lexer member functions
1612 // (for example, BEGIN) use yyg. If we could perform the actions of 1612 // (for example, BEGIN) use yyg. If we could perform the actions of
1613 // these macros with functions instead, we could eliminate the 1613 // these macros with functions instead, we could eliminate the
1614 // OCTAVE_YYG macro. 1614 // OCTAVE_YYG macro.
1615 1615
1616 #define OCTAVE_YYG \ 1616 #define OCTAVE_YYG \
1617 struct yyguts_t *yyg = static_cast<struct yyguts_t*> (scanner) 1617 struct yyguts_t *yyg = static_cast<struct yyguts_t*> (scanner)
1618 1618
1619 void 1619 void
1620 octave_lexer::reset (void) 1620 octave_base_lexer::reset (void)
1621 { 1621 {
1622 // Start off on the right foot. 1622 // Start off on the right foot.
1623 clear_start_state (); 1623 clear_start_state ();
1624 1624
1625 parser_symtab_context.clear (); 1625 parser_symtab_context.clear ();
1636 || reading_classdef_file 1636 || reading_classdef_file
1637 || reading_script_file 1637 || reading_script_file
1638 || input_from_eval_string ())) 1638 || input_from_eval_string ()))
1639 yyrestart (stdin, scanner); 1639 yyrestart (stdin, scanner);
1640 1640
1641 input_reader.reset ();
1642
1643 lexical_feedback::reset (); 1641 lexical_feedback::reset ();
1644 } 1642 }
1645 1643
1646 void 1644 void
1647 octave_lexer::prep_for_file (void) 1645 octave_base_lexer::prep_for_file (void)
1648 { 1646 {
1649 reading_script_file = true; 1647 reading_script_file = true;
1650 1648
1651 push_start_state (INPUT_FILE_START); 1649 push_start_state (INPUT_FILE_START);
1652 } 1650 }
1653 1651
1654 int 1652 int
1655 octave_lexer::read (char *buf, unsigned max_size) 1653 octave_base_lexer::handle_end_of_input (void)
1656 {
1657 int status = 0;
1658
1659 if (input_buf.empty ())
1660 {
1661 bool eof = false;
1662 current_input_line = input_reader.get_input (eof);
1663 input_buf.fill (current_input_line, eof);
1664 }
1665
1666 if (! input_buf.empty ())
1667 status = input_buf.copy_chunk (buf, max_size);
1668 else
1669 {
1670 status = YY_NULL;
1671
1672 if (! input_buf.at_eof ())
1673 fatal_error ("octave_lexer::read () in flex scanner failed");
1674 }
1675
1676 return status;
1677 }
1678
1679 int
1680 octave_lexer::handle_end_of_input (void)
1681 { 1654 {
1682 lexer_debug ("<<EOF>>"); 1655 lexer_debug ("<<EOF>>");
1683 1656
1684 if (block_comment_nesting_level != 0) 1657 if (block_comment_nesting_level != 0)
1685 { 1658 {
1693 1666
1694 return handle_token (END_OF_INPUT); 1667 return handle_token (END_OF_INPUT);
1695 } 1668 }
1696 1669
1697 char * 1670 char *
1698 octave_lexer::flex_yytext (void) 1671 octave_base_lexer::flex_yytext (void)
1699 { 1672 {
1700 return yyget_text (scanner); 1673 return yyget_text (scanner);
1701 } 1674 }
1702 1675
1703 int 1676 int
1704 octave_lexer::flex_yyleng (void) 1677 octave_base_lexer::flex_yyleng (void)
1705 { 1678 {
1706 return yyget_leng (scanner); 1679 return yyget_leng (scanner);
1707 } 1680 }
1708 1681
1709 int 1682 int
1710 octave_lexer::text_yyinput (void) 1683 octave_base_lexer::text_yyinput (void)
1711 { 1684 {
1712 int c = yyinput (scanner); 1685 int c = yyinput (scanner);
1713 1686
1714 if (lexer_debug_flag) 1687 if (lexer_debug_flag)
1715 { 1688 {
1740 1713
1741 return c; 1714 return c;
1742 } 1715 }
1743 1716
1744 void 1717 void
1745 octave_lexer::xunput (char c, char *buf) 1718 octave_base_lexer::xunput (char c, char *buf)
1746 { 1719 {
1747 if (c != EOF) 1720 if (c != EOF)
1748 { 1721 {
1749 if (lexer_debug_flag) 1722 if (lexer_debug_flag)
1750 { 1723 {
1756 yyunput (c, buf, scanner); 1729 yyunput (c, buf, scanner);
1757 } 1730 }
1758 } 1731 }
1759 1732
1760 void 1733 void
1761 octave_lexer::xunput (char c) 1734 octave_base_lexer::xunput (char c)
1762 { 1735 {
1763 char *yytxt = flex_yytext (); 1736 char *yytxt = flex_yytext ();
1764 1737
1765 xunput (c, yytxt); 1738 xunput (c, yytxt);
1766 } 1739 }
1767 1740
1768 bool 1741 bool
1769 octave_lexer::looking_at_space (void) 1742 octave_base_lexer::looking_at_space (void)
1770 { 1743 {
1771 int c = text_yyinput (); 1744 int c = text_yyinput ();
1772 xunput (c); 1745 xunput (c);
1773 return (c == ' ' || c == '\t'); 1746 return (c == ' ' || c == '\t');
1774 } 1747 }
1775 1748
1776 bool 1749 bool
1777 octave_lexer::inside_any_object_index (void) 1750 octave_base_lexer::inside_any_object_index (void)
1778 { 1751 {
1779 bool retval = false; 1752 bool retval = false;
1780 1753
1781 for (std::list<bool>::const_iterator i = looking_at_object_index.begin (); 1754 for (std::list<bool>::const_iterator i = looking_at_object_index.begin ();
1782 i != looking_at_object_index.end (); i++) 1755 i != looking_at_object_index.end (); i++)
1792 } 1765 }
1793 1766
1794 // Handle keywords. Return -1 if the keyword should be ignored. 1767 // Handle keywords. Return -1 if the keyword should be ignored.
1795 1768
1796 int 1769 int
1797 octave_lexer::is_keyword_token (const std::string& s) 1770 octave_base_lexer::is_keyword_token (const std::string& s)
1798 { 1771 {
1799 int l = input_line_number; 1772 int l = input_line_number;
1800 int c = current_input_column; 1773 int c = current_input_column;
1801 1774
1802 int len = s.length (); 1775 int len = s.length ();
2023 1996
2024 return 0; 1997 return 0;
2025 } 1998 }
2026 1999
2027 bool 2000 bool
2028 octave_lexer::whitespace_is_significant (void) 2001 octave_base_lexer::whitespace_is_significant (void)
2029 { 2002 {
2030 return (nesting_level.is_bracket () 2003 return (nesting_level.is_bracket ()
2031 || (nesting_level.is_brace () 2004 || (nesting_level.is_brace ()
2032 && ! looking_at_object_index.front ())); 2005 && ! looking_at_object_index.front ()));
2033 } 2006 }
2037 { 2010 {
2038 return (len > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')); 2011 return (len > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X'));
2039 } 2012 }
2040 2013
2041 void 2014 void
2042 octave_lexer::handle_number (void) 2015 octave_base_lexer::handle_number (void)
2043 { 2016 {
2044 double value = 0.0; 2017 double value = 0.0;
2045 int nread = 0; 2018 int nread = 0;
2046 2019
2047 char *yytxt = flex_yytext (); 2020 char *yytxt = flex_yytext ();
2080 2053
2081 current_input_column += flex_yyleng (); 2054 current_input_column += flex_yyleng ();
2082 } 2055 }
2083 2056
2084 void 2057 void
2085 octave_lexer::handle_continuation (void) 2058 octave_base_lexer::handle_continuation (void)
2086 { 2059 {
2087 char *yytxt = flex_yytext (); 2060 char *yytxt = flex_yytext ();
2088 int yylng = flex_yyleng (); 2061 int yylng = flex_yyleng ();
2089 2062
2090 int offset = 1; 2063 int offset = 1;
2133 input_line_number++; 2106 input_line_number++;
2134 current_input_column = 1; 2107 current_input_column = 1;
2135 } 2108 }
2136 2109
2137 void 2110 void
2138 octave_lexer::finish_comment (octave_comment_elt::comment_type typ, 2111 octave_base_lexer::finish_comment (octave_comment_elt::comment_type typ,
2139 bool looking_at_continuation) 2112 bool looking_at_continuation)
2140 { 2113 {
2141 bool copyright = looks_like_copyright (comment_text); 2114 bool copyright = looks_like_copyright (comment_text);
2142 2115
2143 if (nesting_level.none () && help_text.empty () 2116 if (nesting_level.none () && help_text.empty ()
2144 && ! comment_text.empty () && ! copyright) 2117 && ! comment_text.empty () && ! copyright)
2171 // characters, return 0. Otherwise, return 1. 2144 // characters, return 0. Otherwise, return 1.
2172 2145
2173 // FIXME -- we need to handle block comments here. 2146 // FIXME -- we need to handle block comments here.
2174 2147
2175 bool 2148 bool
2176 octave_lexer::have_continuation (bool trailing_comments_ok) 2149 octave_base_lexer::have_continuation (bool trailing_comments_ok)
2177 { 2150 {
2178 std::ostringstream buf; 2151 std::ostringstream buf;
2179 2152
2180 std::string comment_buf; 2153 std::string comment_buf;
2181 2154
2259 // We have seen a '.' and need to see if it is the start of a 2232 // We have seen a '.' and need to see if it is the start of a
2260 // continuation. If so, this eats it, up to and including the new 2233 // continuation. If so, this eats it, up to and including the new
2261 // line character. 2234 // line character.
2262 2235
2263 bool 2236 bool
2264 octave_lexer::have_ellipsis_continuation (bool trailing_comments_ok) 2237 octave_base_lexer::have_ellipsis_continuation (bool trailing_comments_ok)
2265 { 2238 {
2266 char c1 = text_yyinput (); 2239 char c1 = text_yyinput ();
2267 if (c1 == '.') 2240 if (c1 == '.')
2268 { 2241 {
2269 char c2 = text_yyinput (); 2242 char c2 = text_yyinput ();
2280 2253
2281 return false; 2254 return false;
2282 } 2255 }
2283 2256
2284 int 2257 int
2285 octave_lexer::handle_string (char delim) 2258 octave_base_lexer::handle_string (char delim)
2286 { 2259 {
2287 std::ostringstream buf; 2260 std::ostringstream buf;
2288 2261
2289 int bos_line = input_line_number; 2262 int bos_line = input_line_number;
2290 int bos_col = current_input_column; 2263 int bos_col = current_input_column;
2372 2345
2373 return LEXICAL_ERROR; 2346 return LEXICAL_ERROR;
2374 } 2347 }
2375 2348
2376 int 2349 int
2377 octave_lexer::handle_close_bracket (int bracket_type) 2350 octave_base_lexer::handle_close_bracket (int bracket_type)
2378 { 2351 {
2379 int retval = bracket_type; 2352 int retval = bracket_type;
2380 2353
2381 if (! nesting_level.none ()) 2354 if (! nesting_level.none ())
2382 { 2355 {
2394 2367
2395 return retval; 2368 return retval;
2396 } 2369 }
2397 2370
2398 bool 2371 bool
2399 octave_lexer::looks_like_command_arg (void) 2372 octave_base_lexer::looks_like_command_arg (void)
2400 { 2373 {
2401 bool space_before = space_follows_previous_token (); 2374 bool space_before = space_follows_previous_token ();
2402 bool space_after = looking_at_space (); 2375 bool space_after = looking_at_space ();
2403 2376
2404 return (space_before && ! space_after 2377 return (space_before && ! space_after
2405 && previous_token_may_be_command ()); 2378 && previous_token_may_be_command ());
2406 } 2379 }
2407 2380
2408 int 2381 int
2409 octave_lexer::handle_superclass_identifier (void) 2382 octave_base_lexer::handle_superclass_identifier (void)
2410 { 2383 {
2411 std::string pkg; 2384 std::string pkg;
2412 char *yytxt = flex_yytext (); 2385 char *yytxt = flex_yytext ();
2413 std::string meth = strip_trailing_whitespace (yytxt); 2386 std::string meth = strip_trailing_whitespace (yytxt);
2414 size_t pos = meth.find ("@"); 2387 size_t pos = meth.find ("@");
2440 2413
2441 return SUPERCLASSREF; 2414 return SUPERCLASSREF;
2442 } 2415 }
2443 2416
2444 int 2417 int
2445 octave_lexer::handle_meta_identifier (void) 2418 octave_base_lexer::handle_meta_identifier (void)
2446 { 2419 {
2447 std::string pkg; 2420 std::string pkg;
2448 char *yytxt = flex_yytext (); 2421 char *yytxt = flex_yytext ();
2449 std::string cls = strip_trailing_whitespace (yytxt).substr (1); 2422 std::string cls = strip_trailing_whitespace (yytxt).substr (1);
2450 size_t pos = cls.find ("."); 2423 size_t pos = cls.find (".");
2475 // Figure out exactly what kind of token to return when we have seen 2448 // Figure out exactly what kind of token to return when we have seen
2476 // an identifier. Handles keywords. Return -1 if the identifier 2449 // an identifier. Handles keywords. Return -1 if the identifier
2477 // should be ignored. 2450 // should be ignored.
2478 2451
2479 int 2452 int
2480 octave_lexer::handle_identifier (void) 2453 octave_base_lexer::handle_identifier (void)
2481 { 2454 {
2482 char *yytxt = flex_yytext (); 2455 char *yytxt = flex_yytext ();
2483 2456
2484 std::string tok = yytxt; 2457 std::string tok = yytxt;
2485 2458
2576 2549
2577 return NAME; 2550 return NAME;
2578 } 2551 }
2579 2552
2580 void 2553 void
2581 octave_lexer::maybe_warn_separator_insert (char sep) 2554 octave_base_lexer::maybe_warn_separator_insert (char sep)
2582 { 2555 {
2583 std::string nm = fcn_file_full_name; 2556 std::string nm = fcn_file_full_name;
2584 2557
2585 if (nm.empty ()) 2558 if (nm.empty ())
2586 warning_with_id ("Octave:separator-insert", 2559 warning_with_id ("Octave:separator-insert",
2591 "potential auto-insertion of '%c' near line %d of file %s", 2564 "potential auto-insertion of '%c' near line %d of file %s",
2592 sep, input_line_number, nm.c_str ()); 2565 sep, input_line_number, nm.c_str ());
2593 } 2566 }
2594 2567
2595 void 2568 void
2596 octave_lexer::gripe_single_quote_string (void) 2569 octave_base_lexer::gripe_single_quote_string (void)
2597 { 2570 {
2598 std::string nm = fcn_file_full_name; 2571 std::string nm = fcn_file_full_name;
2599 2572
2600 if (nm.empty ()) 2573 if (nm.empty ())
2601 warning_with_id ("Octave:single-quote-string", 2574 warning_with_id ("Octave:single-quote-string",
2606 "single quote delimited string near line %d of file %s", 2579 "single quote delimited string near line %d of file %s",
2607 input_line_number, nm.c_str ()); 2580 input_line_number, nm.c_str ());
2608 } 2581 }
2609 2582
2610 void 2583 void
2611 octave_lexer::gripe_matlab_incompatible (const std::string& msg) 2584 octave_base_lexer::gripe_matlab_incompatible (const std::string& msg)
2612 { 2585 {
2613 std::string nm = fcn_file_full_name; 2586 std::string nm = fcn_file_full_name;
2614 2587
2615 if (nm.empty ()) 2588 if (nm.empty ())
2616 warning_with_id ("Octave:matlab-incompatible", 2589 warning_with_id ("Octave:matlab-incompatible",
2621 "potential Matlab compatibility problem: %s near line %d offile %s", 2594 "potential Matlab compatibility problem: %s near line %d offile %s",
2622 msg.c_str (), input_line_number, nm.c_str ()); 2595 msg.c_str (), input_line_number, nm.c_str ());
2623 } 2596 }
2624 2597
2625 void 2598 void
2626 octave_lexer::maybe_gripe_matlab_incompatible_comment (char c) 2599 octave_base_lexer::maybe_gripe_matlab_incompatible_comment (char c)
2627 { 2600 {
2628 if (c == '#') 2601 if (c == '#')
2629 gripe_matlab_incompatible ("# used as comment character"); 2602 gripe_matlab_incompatible ("# used as comment character");
2630 } 2603 }
2631 2604
2632 void 2605 void
2633 octave_lexer::gripe_matlab_incompatible_continuation (void) 2606 octave_base_lexer::gripe_matlab_incompatible_continuation (void)
2634 { 2607 {
2635 gripe_matlab_incompatible ("\\ used as line continuation marker"); 2608 gripe_matlab_incompatible ("\\ used as line continuation marker");
2636 } 2609 }
2637 2610
2638 void 2611 void
2639 octave_lexer::gripe_matlab_incompatible_operator (const std::string& op) 2612 octave_base_lexer::gripe_matlab_incompatible_operator (const std::string& op)
2640 { 2613 {
2641 std::string t = op; 2614 std::string t = op;
2642 int n = t.length (); 2615 int n = t.length ();
2643 if (t[n-1] == '\n') 2616 if (t[n-1] == '\n')
2644 t.resize (n-1); 2617 t.resize (n-1);
2645 gripe_matlab_incompatible (t + " used as operator"); 2618 gripe_matlab_incompatible (t + " used as operator");
2646 } 2619 }
2647 2620
2648 void 2621 void
2649 octave_lexer::push_token (token *tok) 2622 octave_base_lexer::push_token (token *tok)
2650 { 2623 {
2651 YYSTYPE *lval = yyget_lval (scanner); 2624 YYSTYPE *lval = yyget_lval (scanner);
2652 lval->tok_val = tok; 2625 lval->tok_val = tok;
2653 tokens.push (tok); 2626 tokens.push (tok);
2654 } 2627 }
2655 2628
2656 token * 2629 token *
2657 octave_lexer::current_token (void) 2630 octave_base_lexer::current_token (void)
2658 { 2631 {
2659 YYSTYPE *lval = yyget_lval (scanner); 2632 YYSTYPE *lval = yyget_lval (scanner);
2660 return lval->tok_val; 2633 return lval->tok_val;
2661 } 2634 }
2662 2635
2663 void 2636 void
2664 octave_lexer::display_token (int tok) 2637 octave_base_lexer::display_token (int tok)
2665 { 2638 {
2666 switch (tok) 2639 switch (tok)
2667 { 2640 {
2668 case '=': std::cerr << "'='\n"; break; 2641 case '=': std::cerr << "'='\n"; break;
2669 case ':': std::cerr << "':'\n"; break; 2642 case ':': std::cerr << "':'\n"; break;
2795 break; 2768 break;
2796 } 2769 }
2797 } 2770 }
2798 2771
2799 void 2772 void
2800 octave_lexer::fatal_error (const char *msg) 2773 octave_base_lexer::fatal_error (const char *msg)
2801 { 2774 {
2802 error (msg); 2775 error (msg);
2803 2776
2804 OCTAVE_QUIT; 2777 OCTAVE_QUIT;
2805 2778
2806 yy_fatal_error (msg, scanner); 2779 yy_fatal_error (msg, scanner);
2807 } 2780 }
2808 2781
2809 void 2782 void
2810 octave_lexer::lexer_debug (const char *pattern) 2783 octave_base_lexer::lexer_debug (const char *pattern)
2811 { 2784 {
2812 if (lexer_debug_flag) 2785 if (lexer_debug_flag)
2813 { 2786 {
2814 std::cerr << std::endl; 2787 std::cerr << std::endl;
2815 2788
2819 std::cerr << "T: " << flex_yytext () << std::endl; 2792 std::cerr << "T: " << flex_yytext () << std::endl;
2820 } 2793 }
2821 } 2794 }
2822 2795
2823 void 2796 void
2824 octave_lexer::push_start_state (int state) 2797 octave_base_lexer::push_start_state (int state)
2825 { 2798 {
2826 OCTAVE_YYG; 2799 OCTAVE_YYG;
2827 2800
2828 start_state_stack.push (state); 2801 start_state_stack.push (state);
2829 2802
2830 BEGIN (start_state ()); 2803 BEGIN (start_state ());
2831 } 2804 }
2832 2805
2833 void 2806 void
2834 octave_lexer::pop_start_state (void) 2807 octave_base_lexer::pop_start_state (void)
2835 { 2808 {
2836 OCTAVE_YYG; 2809 OCTAVE_YYG;
2837 2810
2838 start_state_stack.pop (); 2811 start_state_stack.pop ();
2839 2812
2840 BEGIN (start_state ()); 2813 BEGIN (start_state ());
2841 } 2814 }
2842 2815
2843 void 2816 void
2844 octave_lexer::clear_start_state (void) 2817 octave_base_lexer::clear_start_state (void)
2845 { 2818 {
2846 while (! start_state_stack.empty ()) 2819 while (! start_state_stack.empty ())
2847 start_state_stack.pop (); 2820 start_state_stack.pop ();
2848 2821
2849 push_start_state (INITIAL); 2822 push_start_state (INITIAL);
2850 } 2823 }
2851 2824
2852 void 2825 void
2853 octave_lexer::display_start_state (void) const 2826 octave_base_lexer::display_start_state (void) const
2854 { 2827 {
2855 std::cerr << "S: "; 2828 std::cerr << "S: ";
2856 2829
2857 switch (start_state ()) 2830 switch (start_state ())
2858 { 2831 {
2885 break; 2858 break;
2886 } 2859 }
2887 } 2860 }
2888 2861
2889 int 2862 int
2890 octave_lexer::handle_op (const char *pattern, int tok, bool bos) 2863 octave_base_lexer::handle_op (const char *pattern, int tok, bool bos)
2891 { 2864 {
2892 lexer_debug (pattern); 2865 lexer_debug (pattern);
2893 2866
2894 return handle_op_internal (tok, bos, true); 2867 return handle_op_internal (tok, bos, true);
2895 } 2868 }
2896 2869
2897 int 2870 int
2898 octave_lexer::handle_incompatible_op (const char *pattern, int tok, bool bos) 2871 octave_base_lexer::handle_incompatible_op (const char *pattern, int tok,
2872 bool bos)
2899 { 2873 {
2900 lexer_debug (pattern); 2874 lexer_debug (pattern);
2901 2875
2902 return handle_op_internal (tok, bos, false); 2876 return handle_op_internal (tok, bos, false);
2903 } 2877 }
2904 2878
2905 bool 2879 bool
2906 octave_lexer::maybe_unput_comma_before_unary_op (int tok) 2880 octave_base_lexer::maybe_unput_comma_before_unary_op (int tok)
2907 { 2881 {
2908 int prev_tok = previous_token_value (); 2882 int prev_tok = previous_token_value ();
2909 2883
2910 bool unput_comma = false; 2884 bool unput_comma = false;
2911 2885
2924 2898
2925 return unput_comma; 2899 return unput_comma;
2926 } 2900 }
2927 2901
2928 int 2902 int
2929 octave_lexer::handle_unary_op (int tok, bool bos) 2903 octave_base_lexer::handle_unary_op (int tok, bool bos)
2930 { 2904 {
2931 return maybe_unput_comma_before_unary_op (tok) 2905 return maybe_unput_comma_before_unary_op (tok)
2932 ? -1 : handle_op_internal (tok, bos, true); 2906 ? -1 : handle_op_internal (tok, bos, true);
2933 } 2907 }
2934 2908
2935 int 2909 int
2936 octave_lexer::handle_incompatible_unary_op (int tok, bool bos) 2910 octave_base_lexer::handle_incompatible_unary_op (int tok, bool bos)
2937 { 2911 {
2938 return maybe_unput_comma_before_unary_op (tok) 2912 return maybe_unput_comma_before_unary_op (tok)
2939 ? -1 : handle_op_internal (tok, bos, false); 2913 ? -1 : handle_op_internal (tok, bos, false);
2940 } 2914 }
2941 2915
2942 int 2916 int
2943 octave_lexer::handle_op_internal (int tok, bool bos, bool compat) 2917 octave_base_lexer::handle_op_internal (int tok, bool bos, bool compat)
2944 { 2918 {
2945 if (! compat) 2919 if (! compat)
2946 gripe_matlab_incompatible_operator (flex_yytext ()); 2920 gripe_matlab_incompatible_operator (flex_yytext ());
2947 2921
2948 push_token (new token (tok, input_line_number, current_input_column)); 2922 push_token (new token (tok, input_line_number, current_input_column));
2953 2927
2954 return count_token (tok); 2928 return count_token (tok);
2955 } 2929 }
2956 2930
2957 int 2931 int
2958 octave_lexer::handle_token (const std::string& name, int tok) 2932 octave_base_lexer::handle_token (const std::string& name, int tok)
2959 { 2933 {
2960 token *tok_val = new token (tok, name, input_line_number, 2934 token *tok_val = new token (tok, name, input_line_number,
2961 current_input_column); 2935 current_input_column);
2962 2936
2963 return handle_token (tok, tok_val); 2937 return handle_token (tok, tok_val);
2964 } 2938 }
2965 2939
2966 int 2940 int
2967 octave_lexer::handle_token (int tok, token *tok_val) 2941 octave_base_lexer::handle_token (int tok, token *tok_val)
2968 { 2942 {
2969 if (! tok_val) 2943 if (! tok_val)
2970 tok_val = new token (tok, input_line_number, current_input_column); 2944 tok_val = new token (tok, input_line_number, current_input_column);
2971 2945
2972 push_token (tok_val); 2946 push_token (tok_val);
2975 2949
2976 return count_token_internal (tok); 2950 return count_token_internal (tok);
2977 } 2951 }
2978 2952
2979 int 2953 int
2980 octave_lexer::count_token (int tok) 2954 octave_base_lexer::count_token (int tok)
2981 { 2955 {
2982 token *tok_val = new token (tok, input_line_number, current_input_column); 2956 token *tok_val = new token (tok, input_line_number, current_input_column);
2983 2957
2984 push_token (tok_val); 2958 push_token (tok_val);
2985 2959
2986 return count_token_internal (tok); 2960 return count_token_internal (tok);
2987 } 2961 }
2988 2962
2989 int 2963 int
2990 octave_lexer::count_token_internal (int tok) 2964 octave_base_lexer::count_token_internal (int tok)
2991 { 2965 {
2992 if (tok != '\n') 2966 if (tok != '\n')
2993 { 2967 {
2994 Vtoken_count++; 2968 Vtoken_count++;
2995 token_count++; 2969 token_count++;
2997 2971
2998 return show_token (tok); 2972 return show_token (tok);
2999 } 2973 }
3000 2974
3001 int 2975 int
3002 octave_lexer::show_token (int tok) 2976 octave_base_lexer::show_token (int tok)
3003 { 2977 {
3004 if (Vdisplay_tokens) 2978 if (Vdisplay_tokens)
3005 display_token (tok); 2979 display_token (tok);
3006 2980
3007 if (lexer_debug_flag) 2981 if (lexer_debug_flag)
3011 std::cerr << std::endl; 2985 std::cerr << std::endl;
3012 } 2986 }
3013 2987
3014 return tok; 2988 return tok;
3015 } 2989 }
2990
2991 int
2992 octave_lexer::fill_flex_buffer (char *buf, unsigned max_size)
2993 {
2994 int status = 0;
2995
2996 if (input_buf.empty ())
2997 {
2998 bool eof = false;
2999 current_input_line = input_reader.get_input (eof);
3000 input_buf.fill (current_input_line, eof);
3001 }
3002
3003 if (! input_buf.empty ())
3004 status = input_buf.copy_chunk (buf, max_size);
3005 else
3006 {
3007 status = YY_NULL;
3008
3009 if (! input_buf.at_eof ())
3010 fatal_error ("octave_base_lexer::fill_flex_buffer failed");
3011 }
3012
3013 return status;
3014 }