Re: Suspend the parser

Cheng-Chang Wu <chengchangwu-/[email protected]>
Newsgroups gmane.comp.lang.eiffel.gobo.general
Message-ID <[email protected]>
Attached files are removed in last email?

Here are they again.

--- Cheng-Chang Wu <chengchangwu-/[email protected]> wrote:

> For my application the proccess must jump out from
> the
> parser and jump in later. I've written a feature
> 'suspend' to save the local variables of feature
> 'parse', and redefined feature 'parse' so when it is
> called next time, it can resume its job.
> 
> I am not sure if I've done it right. Maybe someone
> have interest to look in the two attached classes.
> 

class CNC_PARSER_SKELETON

inherit

        YY_NEW_PARSER_SKELETON
                redefine
                        parse
                end

feature -- Status report

        is_suspended: BOOLEAN is
                do
                        Result := yy_parsing_status =
yySuspended
                end

feature {YY_PARSER_ACTION} -- Element change

        suspend is
                        -- Suspend parsing.
                do
                        yy_parsing_status :=
yySuspended
                ensure
                        suspended: is_suspended
                end

feature -- Parsing

        parse is
                        -- Parse input stream.
                        -- Set `syntax_error' to True
if
                        -- parsing has not been
successful.
                local
                        yystacksize: INTEGER
                        yystate: INTEGER
                        yyn: INTEGER
                        yychar1: INTEGER
                        index, yyss_top: INTEGER
                        yy_goto: INTEGER
                do
                                -- This routine is
implemented with a loop whose body
                                -- is a big inspect
instruction. This is a mere
                                -- translation of C
gotos into Eiffel. Needless to
                                -- say that I'm not
very proud of this piece of code.
                                -- However I performed
some benchmarks and the results
                                -- were that this
implementation runs amazingly faster
                                -- than an alternative
implementation with no loop nor
                                -- inspect
instructions and where every branch of the
                                -- old inspect
instruction was written in a separate
                                -- routine. I think
that the performance penalty is due
                                -- to the routine call
overhead and the depth of the call
                                -- stack. Anyway, I
prefer to provide you with a big and
                                -- ugly but fast
parsing routine rather than a nice and
                                -- slow version. I
hope you won't blame me for that! :-)
                        from
                                if yy_parsing_status =
yySuspended then
                                        yystacksize :=
suspended_state.yystacksize
                                        yystate :=
suspended_state.yystate
                                        yyn :=
suspended_state.yyn
                                        yychar1 :=
suspended_state.yychar1
                                        index :=
suspended_state.index
                                        yyss_top :=
suspended_state.yyss_top
                                        yy_goto :=
suspended_state.yy_goto
                                       
yy_parsing_status := yyContinue
                                else
                                        error_count :=
0
                                       
yy_lookahead_needed := True
                                        yyerrstatus :=
0
                                       
yy_init_value_stacks
                                        yyssp := -1
                                        yystacksize :=
yyss.count
                                       
yy_parsing_status := yyContinue
                                        yy_goto :=
yyNewstate
                                end
                        until
                                yy_parsing_status /=
yyContinue
                        loop
                                inspect yy_goto
                                when yyNewstate then
                                        yyssp := yyssp
+ 1
                                        if yyssp >=
yystacksize then
                                               
yystacksize := yystacksize + yyInitial_stack_size
                                                yyss
:= FIXED_INTEGER_ARRAY_.resize (yyss, yystacksize)
                                                debug
("GEYACC")
                                                      
 std.error.put_string ("Stack (yyss) size increased to
")
                                                      
 std.error.put_integer (yystacksize)
                                                      
 std.error.put_character ('%N')
                                                end
                                        end
                                        debug
("GEYACC")
                                               
std.error.put_string ("Entering state ")
                                               
std.error.put_integer (yystate)
                                               
std.error.put_character ('%N')
                                        end
                                        yyss.put
(yystate, yyssp)
                                                -- Do
appropriate processing given the current state.
                                                --
Read a lookahead token if one is needed.
                                        yyn :=
yypact.item (yystate)
                                                --
First try to decide what to do without reference
                                                --
lookahead token.
                                        if yyn =
yyFlag then
                                               
yy_goto := yyDefault
                                        else
                                                      
 -- Not known => get a lookahead token if don't
                                                      
 -- already have one.
                                                if
yy_lookahead_needed then
                                                      
 debug ("GEYACC")
                                                      
         std.error.put_string ("Reading a token%N")
                                                      
 end
                                                      
 read_token
                                                      
 yy_lookahead_needed := False
                                                end
                                                      
 -- Convert token to internal form (in `yychar1')
                                                      
 -- for indexing tables.
                                                if
last_token > yyEof then
                                                      
 debug ("GEYACC")
                                                      
         std.error.put_string ("Next token is ")
                                                      
         std.error.put_integer (last_token)
                                                      
         std.error.put_character ('%N')
                                                      
 end
                                                      
         -- Translate lexical token `last_token' into
                                                      
         -- geyacc internal token code.
                                                      
 if last_token <= yyMax_token then
                                                      
         yychar1 := yytranslate.item (last_token)
                                                      
 else
                                                      
         yychar1 := yyNsyms
                                                      
 end
                                                      
 yyn := yyn + yychar1
                                                elseif
last_token = yyEof then
                                                      
         -- This means end of input.
                                                      
 debug ("GEYACC")
                                                      
         std.error.put_string ("Now at end of
input.%N")
                                                      
 end
                                                      
 yychar1 := 0
                                                else
                                                      
         -- An error occurred in the scanner.
                                                      
 debug ("GEYACC")
                                                      
         std.error.put_string ("Error in scanner.%N")
                                                      
 end
                                                      
 error_count := error_count + 1
                                                      
 yy_do_error_action (yystate)
                                                      
 abort
                                                      
         -- Skip next conditional instruction:
                                                      
 yyn := -1
                                                end
                                                if
                                                      
 (yyn < 0 or yyn > yyLast) or else
                                                      
 yycheck.item (yyn) /= yychar1
                                                then
                                                      
 yy_goto := yyDefault
                                                else
                                                      
 yyn := yytable.item (yyn)
                                                      
         -- `yyn' is what to do for this token type in
                                                      
         -- this state:
                                                      
         -- Negative => reduce, -`yyn' is rule number.
                                                      
         -- Positive => shift, `yyn' is new state.
                                                      
         -- New state is final state => don't bother
to
                                                      
         --              shift, just return success.
                                                      
         -- 0, or most negative number => error.
                                                      
 if yyn < 0 then
                                                      
         if yyn = yyFlag then
                                                      
                 yy_goto := yyErrlab
                                                      
         else
                                                      
                 yyn := -yyn
                                                      
                 yy_goto := yyReduce
                                                      
         end
                                                      
 elseif yyn = 0 then
                                                      
         yy_goto := yyErrlab
                                                      
 elseif yyn = yyFinal then
                                                      
         accept
                                                      
 else
                                                      
                 -- Shift the lookahead token.
                                                      
         debug ("GEYACC")
                                                      
                 std.error.put_string ("Shifting token
")
                                                      
                 std.error.put_integer (last_token)
                                                      
                 std.error.put_character ('%N')
                                                      
         end
                                                      
                 -- Discard the token being shifted
                                                      
                 -- unless it is eof.
                                                      
         if last_token > yyEof then
                                                      
                 yy_lookahead_needed := True
                                                      
         end
                                                      
         yy_push_last_value (yychar1)
                                                      
                 -- Count tokens shifted since error;
                                                      
                 -- after three, turn off error
status.
                                                      
         if yyerrstatus /= 0 then
                                                      
                 yyerrstatus := yyerrstatus - 1
                                                      
         end
                                                      
         yystate := yyn
                                                      
         check
                                                      
                 newstate: yy_goto = yyNewstate
                                                      
         end
                                                      
 end
                                                end
                                        end
                                when yyDefault then
                                                -- Do
the default action for the current state.
                                        yyn :=
yydefact.item (yystate)
                                        if yyn = 0
then
                                               
yy_goto := yyErrlab
                                        else
                                               
yy_goto := yyReduce
                                        end
                                when yyReduce then
                                                -- Do
a reduction. `yyn' is the number of a rule
                                                -- to
reduce with.
                                        debug
("GEYACC")
                                               
std.error.put_string ("Reducing via rule #")
                                               
std.error.put_integer (yyn)
                                               
std.error.put_character ('%N')
                                        end
                                        yy_do_action
(yyn)
                                        if
yy_parsing_status = yyContinue then
                                                      
 -- Now "shift" the result of the reduction.
                                                      
 -- Determine what state that goes to,
                                                      
 -- based on the state we popped back to
                                                      
 -- and the rule number reduced by.
                                                yyn :=
yyr1.item (yyn)
                                               
yyss_top := yyss.item (yyssp)
                                                index
:= yyn - yyNtbase
                                               
yystate := yypgoto.item (index) + yyss_top
                                                if
                                                      
 (yystate >= 0 and yystate <= yyLast) and then
                                                      
 yycheck.item (yystate) = yyss_top
                                                then
                                                      
 yystate := yytable.item (yystate)
                                                else
                                                      
 yystate := yydefgoto.item (index)
                                                end
                                               
yy_goto := yyNewstate
                                        elseif
yy_parsing_status = yySuspended then
                                                if
suspended_state = Void then
                                                      
 create suspended_state.make
                                                end
                                               
suspended_state.set_yystacksize (yystacksize)
                                               
suspended_state.set_yystate (yystate)
                                               
suspended_state.set_yyn (yyn)
                                               
suspended_state.set_yychar1 (yychar1)
                                               
suspended_state.set_index (index)
                                               
suspended_state.set_yyss_top (yyss_top)
                                               
suspended_state.set_yy_goto (yy_goto)
                                        elseif
yy_parsing_status = yyError_raised then
                                                      
 -- Handle error raised explicitly by an action.
                                               
yy_parsing_status := yyContinue
                                               
yy_goto := yyErrlab
                                        -- else
                                                      
 -- Accepted or aborted.
                                        end
                                when yyErrlab then
                                                --
Detect error.
                                        if yyerrstatus
= 3 then
                                                      
 -- If just tried and failed to reuse lookahead
                                                      
 -- token after an error, discard it. Return
                                                      
 -- failure if at end of input.
                                                if
last_token <= yyEof then
                                                      
 abort
                                                else
                                                      
 debug ("GEYACC")
                                                      
         std.error.put_string ("Discarding token ")
                                                      
         std.error.put_integer (last_token)
                                                      
         std.error.put_character ('%N')
                                                      
 end
                                                      
 yy_lookahead_needed := True
                                                      
 yy_goto := yyErrhandle
                                                end
                                        else
                                                if
yyerrstatus = 0 then
                                                      
         -- If not already recovering from an error,
                                                      
         -- report this error.
                                                      
 error_count := error_count + 1
                                                      
 yy_do_error_action (yystate)
                                                end
                                               
yyerrstatus := 3
                                               
yy_goto := yyErrhandle
                                        end
                                when yyErrhandle then
                                                --
Handle error.
                                        yyn :=
yypact.item (yystate)
                                        if yyn =
yyFlag then
                                               
yy_goto := yyErrpop
                                        else
                                                yyn :=
yyn + yyTerror
                                                if
                                                      
 (yyn < 0 or yyn > yyLast) or else
                                                      
 yycheck.item (yyn) /= yyTerror
                                                then
                                                      
 yy_goto := yyErrpop
                                                else
                                                      
 yyn := yytable.item (yyn)
                                                      
 if yyn < 0 then
                                                      
         if yyn = yyFlag then
                                                      
                 yy_goto := yyErrpop
                                                      
         else
                                                      
                 yyn := -yyn
                                                      
                 yy_goto := yyReduce
                                                      
         end
                                                      
 elseif yyn = 0 then
                                                      
         yy_goto := yyErrpop
                                                      
 elseif yyn = yyFinal then
                                                      
         accept
                                                      
 else
                                                      
         yy_push_error_value
                                                      
         yystate := yyn
                                                      
         yy_goto := yyNewstate
                                                      
 end
                                                end
                                        end
                                when yyErrpop then
                                                -- Pop
the current state because it cannot handle
                                                -- the
error token.
                                        if yyssp = 0
then
                                                abort
                                        else
                                               
yy_pop_last_value (yystate)
                                                yyssp
:= yyssp - 1
                                               
yystate := yyss.item (yyssp)
                                               
yy_goto := yyErrhandle
                                        end
                                end
                        end
                        if yy_parsing_status /=
yySuspended then
                                yy_clear_all
                        end
                rescue
                        debug ("GEYACC")
                                std.error.put_line
("Entering rescue clause of parser")
                        end
                        abort
                        yy_clear_all
                end

feature {NONE} -- Constants

        yySuspended: INTEGER is unique

feature {NONE} -- Suspended state

        suspended_state: CNC_PARSER_SUSPENDED_STATE

end


class CNC_PARSER_SUSPENDED_STATE

create {CNC_PARSER_SKELETON}

        make

feature {NONE} -- Initialization

        make is
                do
                end

feature {CNC_PARSER_SKELETON} -- Access

        yystacksize: INTEGER
        yystate: INTEGER
        yyn: INTEGER
        yychar1: INTEGER
        index: INTEGER
        yyss_top: INTEGER
        yy_goto: INTEGER

feature {CNC_PARSER_SKELETON} -- Setting

        set_yystacksize (v: INTEGER) is
                do
                        yystacksize := v
                ensure
                        yystacksize_set: yystacksize =
v
                end

        set_yystate (v: INTEGER) is
                do
                        yystate := v
                ensure
                        yystate_set: yystate = v
                end

        set_yyn (v: INTEGER) is
                do
                        yyn := v
                ensure
                        yyn_set: yyn = v
                end

        set_yychar1 (v: INTEGER) is
                do
                        yychar1 := v
                ensure
                        yychar1_set: yychar1 = v
                end
        set_index (v: INTEGER) is
                do
                        index := v
                ensure
                        index_set: index = v
                end

        set_yyss_top (v: INTEGER) is
                do
                        yyss_top := v
                ensure
                        yyss_top_set: yyss_top = v
                end

        set_yy_goto (v: INTEGER) is
                do
                        yy_goto := v
                ensure
                        yy_goto_set: yy_goto = v
                end

end



		
__________________________________ 
Start your day with Yahoo! - Make it your home page! 
http://www.yahoo.com/r/hs


------------------------ Yahoo! Groups Sponsor --------------------~--> 
Get Bzzzy! (real tools to help you find a job). Welcome to the Sweet Life.
http://us.click.yahoo.com/A77XvD/vlQLAA/TtwFAA/saFolB/TM
--------------------------------------------------------------------~-> 

To Post a message, send it to:   [email protected]
To Unsubscribe, send a blank message to: [email protected] 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/gobo-eiffel/

<*> To unsubscribe from this group, send an email to:
    [email protected]

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.