Mercurial > hg > octave-nkf
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 } |