PageRenderTime 18ms CodeModel.GetById 15ms app.highlight 1ms RepoModel.GetById 1ms app.codeStats 0ms

/src/lib/parse/descending_parser.e

http://github.com/tybor/Liberty
Specman e | 172 lines | 128 code | 13 blank | 31 comment | 6 complexity | 9d5e7c737259e9117995a8455df61375 MD5 | raw file
  1-- This file is part of a Liberty Eiffel library.
  2-- See the full copyright at the end.
  3--
  4class DESCENDING_PARSER
  5   --
  6   -- The entry point to LL(n) parsing. Currently that top-down parsing is directly implemented in the
  7   -- PARSE_ATOM classes.
  8   --
  9
 10insert
 11   TRISTATE_VALUES
 12   LOGGING
 13
 14creation {ANY}
 15   make
 16
 17feature {ANY}
 18   parse (buffer: MINI_PARSER_BUFFER; grammar: PARSE_TABLE; start: STRING; a_actions: COLLECTION[PARSE_ACTION]): BOOLEAN is
 19         -- Returns True if the parsing succeeded or definitely could not succeed, False if some more text
 20         -- could make it succeed.
 21      require
 22         a_actions /= Void
 23         grammar.is_coherent
 24         grammar.has(start)
 25      local
 26         atom: PARSE_ATOM
 27         parsed: TRISTATE
 28      do
 29         error := Void
 30         atom := grammar.item(start)
 31         parsed := atom.parse(buffer, a_actions)
 32         if parsed = yes then
 33            Result := True
 34         elseif parsed = no then
 35            error := buffer.last_error
 36            if error = Void then
 37               create error.make(1, once "This does not look like Eiffel, not even remotely.", Void)
 38            end
 39            Result := True
 40         else
 41            check
 42               should_add_more: not Result
 43            end
 44         end
 45      ensure
 46         a_actions.count >= old a_actions.count
 47      end
 48
 49   eval (buffer: MINI_PARSER_BUFFER; grammar: PARSE_TABLE; start: STRING): BOOLEAN is
 50         -- Returns True if the parsing succeeded or definitely could not succeed, False if some more text
 51         -- could make it succeed.
 52      local
 53         i: INTEGER
 54      do
 55         save_actions
 56         Result := parse(buffer, grammar, start, actions)
 57         if Result and then error = Void then
 58            debug ("parse")
 59               log.trace.put_line(once "Actions:")
 60               log.trace.put_line(once "--8<-------- <start actions>")
 61               from
 62                  i := actions.lower
 63               until
 64                  i > actions.upper
 65               loop
 66                  log.trace.put_integer(i)
 67                  log.trace.put_character('%T')
 68                  log.trace.put_line(actions.item(i).name)
 69                  i := i + 1
 70               end
 71               log.trace.put_line(once "-------->8-- <end actions>")
 72            end
 73            from
 74               i := actions.lower
 75            until
 76               i > actions.upper
 77            loop
 78               debug ("parse")
 79                  log.trace.put_string(once "Calling action #")
 80                  log.trace.put_integer(i)
 81                  log.trace.put_string(once ": ")
 82                  log.trace.put_line(actions.item(i).name)
 83               end
 84               actions.item(i).call
 85               i := i + 1
 86            end
 87         end
 88         actions.clear_count
 89         restore_actions
 90      end
 91
 92   error: PARSE_ERROR
 93
 94feature {}
 95   make is
 96      do
 97      end
 98
 99   used_actions: FAST_ARRAY[FAST_ARRAY[PARSE_ACTION]] is
100      once
101         create Result.make(0)
102      end
103
104   free_actions: FAST_ARRAY[FAST_ARRAY[PARSE_ACTION]] is
105      once
106         create Result.make(0)
107      end
108
109   actions: FAST_ARRAY[PARSE_ACTION]
110
111   save_actions is
112      do
113         if actions = Void then
114            actions := new_free_actions
115         elseif not actions.is_empty then
116            used_actions.add_last(actions)
117            actions := new_free_actions
118         end
119      ensure
120         actions.is_empty
121         ;(old (actions /= Void and then not actions.is_empty)) implies (used_actions.last = old actions)
122         ;(old (actions /= Void and then not actions.is_empty)) implies (used_actions.count = old used_actions.count + 1)
123      end
124
125   restore_actions is
126      require
127         actions.is_empty
128      do
129         if not used_actions.is_empty then
130            free_actions.add_last(actions)
131            actions := used_actions.last
132            used_actions.remove_last
133         end
134      ensure
135         actions /= Void
136         ;(not old used_actions.is_empty) implies (actions = (old used_actions.twin).last)
137         ;(not old used_actions.is_empty) implies (used_actions.count = old used_actions.count - 1)
138      end
139
140   new_free_actions: like actions is
141      do
142         if free_actions.is_empty then
143            create Result.make(0)
144         else
145            Result := free_actions.last
146            free_actions.remove_last
147         end
148      ensure
149         Result.is_empty
150      end
151
152end -- class DESCENDING_PARSER
153--
154-- Copyright (c) 2009 by all the people cited in the AUTHORS file.
155--
156-- Permission is hereby granted, free of charge, to any person obtaining a copy
157-- of this software and associated documentation files (the "Software"), to deal
158-- in the Software without restriction, including without limitation the rights
159-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
160-- copies of the Software, and to permit persons to whom the Software is
161-- furnished to do so, subject to the following conditions:
162--
163-- The above copyright notice and this permission notice shall be included in
164-- all copies or substantial portions of the Software.
165--
166-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
167-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
168-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
169-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
170-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
171-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
172-- THE SOFTWARE.