# HG changeset patch # User John W. Eaton # Date 1363159175 14400 # Node ID 0925d1f6875e3fcf4cdff3c495d3a2bc08384bad # Parent 57e87ddfee1431ac375ccfef24c475e724a1024c 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. diff -r 57e87ddfee14 -r 0925d1f6875e configure.ac --- a/configure.ac Wed Mar 13 02:46:56 2013 -0400 +++ b/configure.ac Wed Mar 13 03:19:35 2013 -0400 @@ -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 diff -r 57e87ddfee14 -r 0925d1f6875e libinterp/parse-tree/lex.h --- a/libinterp/parse-tree/lex.h Wed Mar 13 02:46:56 2013 -0400 +++ b/libinterp/parse-tree/lex.h Wed Mar 13 03:19:35 2013 -0400 @@ -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 diff -r 57e87ddfee14 -r 0925d1f6875e libinterp/parse-tree/lex.ll --- a/libinterp/parse-tree/lex.ll Wed Mar 13 02:46:56 2013 -0400 +++ b/libinterp/parse-tree/lex.ll Wed Mar 13 03:19:35 2013 -0400 @@ -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 (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; +} diff -r 57e87ddfee14 -r 0925d1f6875e libinterp/parse-tree/oct-parse.in.yy --- a/libinterp/parse-tree/oct-parse.in.yy Wed Mar 13 02:46:56 2013 -0400 +++ b/libinterp/parse-tree/oct-parse.in.yy Wed Mar 13 03:19:35 2013 -0400 @@ -1450,10 +1450,6 @@ octave_base_parser::~octave_base_parser (void) { -#if defined (OCTAVE_USE_PUSH_PARSER) - yypstate_delete (static_cast (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 (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 (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 (parser_state); + + status = octave_push_parse (pstate, token, &lval, *this); + } + while (status == YYPUSH_MORE); + + return status; +} + static void safe_fclose (FILE *f) { diff -r 57e87ddfee14 -r 0925d1f6875e libinterp/parse-tree/parse.h --- a/libinterp/parse-tree/parse.h Wed Mar 13 02:46:56 2013 -0400 +++ b/libinterp/parse-tree/parse.h Wed Mar 13 03:19:35 2013 -0400 @@ -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