Mercurial > hg > octave-jordi
changeset 16294:0925d1f6875e
push parser/lexer interface
* lex.h, lex.ll (octave_push_lexer): New class.
(octave_base_lexer:is_push_lexer, octave_base_lexer::at_end_of_file,
octave_base_lexer::at_end_of_buffer): New functions.
(.): Handle special character (ASCII 0x01) that
octave_push_lexer::fill_flex_buffer returns for an end-of-buffer
condition.
* parse.h, oct-parse.in.yy (octave_push_parser): New class.
(octave_base_parser::parser_state): Move to octave_push_parser class.
(octave_base_parser::~octave_base_parser, octave_base_parser::init):
Delete special case for push parser.
* configure.ac (--enable-push-parser): Delete option handling. Both
push and pull parser interfaces will always be defined.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 13 Mar 2013 03:19:35 -0400 |
parents | 57e87ddfee14 |
children | 4a1300ed5d3c |
files | configure.ac libinterp/parse-tree/lex.h libinterp/parse-tree/lex.ll libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/parse.h |
diffstat | 5 files changed, 163 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.ac +++ b/configure.ac @@ -190,17 +190,6 @@ AC_DEFINE(BOUNDS_CHECKING, 1, [Define to 1 to use internal bounds checking.]) fi -### Enable experimental push parser. - -OCTAVE_USE_PUSH_PARSER=no -AC_ARG_ENABLE([push-parser], - [AS_HELP_STRING([--enable-push-parser], - [enable experimental push parser])], - [if test "$enableval" = yes; then OCTAVE_USE_PUSH_PARSER=yes; fi], []) -if test $OCTAVE_USE_PUSH_PARSER = yes; then - AC_DEFINE(OCTAVE_USE_PUSH_PARSER, 1, [Define to 1 to use experimental push parser.]) -fi - ### Use Octave's built-in memory allocator rather than straightforward malloc. ### Disabled by default. @@ -2980,7 +2969,6 @@ Build Java interface: $build_java Do internal array bounds checking: $BOUNDS_CHECKING Use octave_allocator: $USE_OCTAVE_ALLOCATOR - Use push parser: $OCTAVE_USE_PUSH_PARSER Build static libraries: $STATIC_LIBS Build shared libraries: $SHARED_LIBS Dynamic Linking: $ENABLE_DYNAMIC_LINKING $DL_API_MSG
--- a/libinterp/parse-tree/lex.h +++ b/libinterp/parse-tree/lex.h @@ -438,12 +438,18 @@ void init (void); + virtual bool is_push_lexer (void) const { return false; } + virtual void reset (void); void prep_for_file (void); virtual int fill_flex_buffer (char *buf, unsigned int max_size) = 0; + bool at_end_of_buffer (void) const { return input_buf.empty (); } + + bool at_end_of_file (void) const { return input_buf.at_eof (); } + int handle_end_of_input (void); char *flex_yytext (void); @@ -646,4 +652,58 @@ octave_lexer& operator = (const octave_lexer&); }; +class +octave_push_lexer : public octave_base_lexer +{ +public: + + octave_push_lexer (const std::string& input = std::string (), + bool eof = false) + : octave_base_lexer (), pflag (1) + { + append_input (input, eof); + } + + bool is_push_lexer (void) const { return true; } + + void reset (void) + { + promptflag (1); + + octave_base_lexer::reset (); + } + + void append_input (const std::string& input, bool eof) + { + input_buf.fill (input, eof); + } + + void increment_promptflag (void) { pflag++; } + + void decrement_promptflag (void) { pflag--; } + + int promptflag (void) const { return pflag; } + + int promptflag (int n) + { + int retval = pflag; + pflag = n; + return retval; + } + + std::string input_source (void) const { return "push buffer"; } + + int fill_flex_buffer (char *buf, unsigned int max_size); + +protected: + + int pflag; + + // No copying! + + octave_push_lexer (const octave_push_lexer&); + + octave_push_lexer& operator = (const octave_push_lexer&); +}; + #endif
--- a/libinterp/parse-tree/lex.ll +++ b/libinterp/parse-tree/lex.ll @@ -1129,7 +1129,11 @@ int c = curr_lexer->text_yyinput (); - if (c != EOF) + if (c == 1) + return -1; + else if (c == EOF) + return curr_lexer->handle_end_of_input (); + else { curr_lexer->current_input_column++; @@ -1139,8 +1143,6 @@ return LEXICAL_ERROR; } - else - return curr_lexer->handle_end_of_input (); } %% @@ -3012,3 +3014,24 @@ return status; } + +int +octave_push_lexer::fill_flex_buffer (char *buf, unsigned max_size) +{ + int status = 0; + + if (input_buf.empty () && ! input_buf.at_eof ()) + input_buf.fill (std::string (1, static_cast<char> (1)), false); + + if (! input_buf.empty ()) + status = input_buf.copy_chunk (buf, max_size); + else + { + status = YY_NULL; + + if (! input_buf.at_eof ()) + fatal_error ("octave_base_lexer::fill_flex_buffer failed"); + } + + return status; +}
--- a/libinterp/parse-tree/oct-parse.in.yy +++ b/libinterp/parse-tree/oct-parse.in.yy @@ -1450,10 +1450,6 @@ octave_base_parser::~octave_base_parser (void) { -#if defined (OCTAVE_USE_PUSH_PARSER) - yypstate_delete (static_cast<yypstate *> (parser_state)); -#endif - delete stmt_list; delete &lexer; @@ -1461,10 +1457,6 @@ void octave_base_parser::init (void) { -#if defined (OCTAVE_USE_PUSH_PARSER) - parser_state = yypstate_new (); -#endif - LEXER = &lexer; } @@ -3162,6 +3154,53 @@ return octave_parse (*this); } +octave_push_parser::~octave_push_parser (void) +{ + yypstate_delete (static_cast<yypstate *> (parser_state)); +} + +void +octave_push_parser::init (void) +{ + parser_state = yypstate_new (); + + octave_base_parser::init (); +} + +// Parse input from INPUT. Pass TRUE for EOF if the end of INPUT should +// finish the parse. + +int +octave_push_parser::run (const std::string& input, bool eof) +{ + int status = -1; + + dynamic_cast<octave_push_lexer&> (lexer).append_input (input, eof); + + do + { + YYSTYPE lval; + + int token = octave_lex (&lval, scanner); + + if (token < 0) + { + if (! eof && lexer.at_end_of_buffer ()) + { + status = -1; + break; + } + } + + yypstate *pstate = static_cast<yypstate *> (parser_state); + + status = octave_push_parse (pstate, token, &lval, *this); + } + while (status == YYPUSH_MORE); + + return status; +} + static void safe_fclose (FILE *f) {
--- a/libinterp/parse-tree/parse.h +++ b/libinterp/parse-tree/parse.h @@ -137,7 +137,7 @@ curr_fcn_depth (0), primary_fcn_scope (-1), curr_class_name (), function_scopes (), primary_fcn_ptr (0), stmt_list (0), - lexer (lxr), parser_state (0) + lexer (lxr) { init (); } @@ -383,10 +383,6 @@ // State of the lexer. octave_base_lexer& lexer; - // Internal state of the parser. Only used if USE_PUSH_PARSER is - // defined. - void *parser_state; - private: // No copying! @@ -426,4 +422,33 @@ octave_parser& operator = (const octave_parser&); }; +class +octave_push_parser : public octave_base_parser +{ +public: + + octave_push_parser (void) + : octave_base_parser (*(new octave_push_lexer ())), parser_state (0) + { + init (); + } + + ~octave_push_parser (void); + + void init (void); + + int run (const std::string& input, bool eof); + +private: + + // Internal state of the Bison parser. + void *parser_state; + + // No copying! + + octave_push_parser (const octave_push_parser&); + + octave_push_parser& operator = (const octave_push_parser&); +}; + #endif