/src/lib/parse/parse_table.e

http://github.com/tybor/Liberty · Specman e · 217 lines · 157 code · 19 blank · 41 comment · 4 complexity · a2f0d215e9a14ada9b89938cb8b5eaa8 MD5 · raw file

  1. -- This file is part of a Liberty Eiffel library.
  2. -- See the full copyright at the end.
  3. --
  4. class PARSE_TABLE[C_ -> PARSE_CONTEXT]
  5. --
  6. -- A parsing table (aka Grammar).
  7. --
  8. -- The only way to create a parse table is to use Liberty Eiffel's manifest notation.
  9. --
  10. -- The structure of this notation is:
  11. --
  12. -- {PARSE_TABLE[...] << name, atom;
  13. -- name, atom;
  14. -- . . .
  15. -- name, atom
  16. -- >>}
  17. --
  18. -- where each name is a STRING and each atom may be either a PARSE_NON_TERMINAL or a PARSE_TERMINAL.
  19. --
  20. insert
  21. LOGGING
  22. redefine
  23. out_in_tagged_out_memory
  24. end
  25. create {ANY}
  26. manifest_creation
  27. create {PARSER_FACET}
  28. with_capacity
  29. feature {ANY}
  30. is_coherent: BOOLEAN
  31. -- True if all the used atoms are defined
  32. local
  33. i: INTEGER; atom: PARSE_ATOM[C_]
  34. do
  35. from
  36. Result := True
  37. i := atoms.lower
  38. until
  39. not Result or else i > atoms.upper
  40. loop
  41. atom := atoms.item(i)
  42. Result := atom.is_coherent
  43. if not Result then
  44. breakpoint
  45. end
  46. i := i + 1
  47. end
  48. ensure
  49. must_be_coherent: Result
  50. end
  51. has (atom_name: ABSTRACT_STRING): BOOLEAN
  52. require
  53. not atom_name.is_empty
  54. do
  55. Result := atoms.fast_has(atom_name.intern)
  56. end
  57. set_default_tree_builders (non_terminal_builder: PROCEDURE[TUPLE[FIXED_STRING, TRAVERSABLE[FIXED_STRING]]]; terminal_builder: PROCEDURE[TUPLE[FIXED_STRING, PARSER_IMAGE]])
  58. require
  59. is_coherent
  60. local
  61. i: INTEGER
  62. do
  63. from
  64. i := atoms.lower
  65. until
  66. i > atoms.upper
  67. loop
  68. atoms.item(i).set_default_tree_builders(non_terminal_builder, terminal_builder)
  69. i := i + 1
  70. end
  71. end
  72. extend (a_table: like Current)
  73. -- Extends Current with a *copy* of the atoms of `a_table'. Any atom with a name already existing in
  74. -- Current is ignored.
  75. require
  76. a_table /= Void
  77. a_table /= Current
  78. local
  79. i: INTEGER; atom: PARSE_ATOM[C_]
  80. do
  81. from
  82. i := a_table.atoms.lower
  83. until
  84. i > a_table.atoms.upper
  85. loop
  86. if not atoms.fast_has(a_table.atoms.key(i)) then
  87. atom := a_table.atoms.item(i).twin
  88. atom.set_table(Current)
  89. atoms.add(atom, a_table.atoms.key(i))
  90. end
  91. i := i + 1
  92. end
  93. end
  94. add_or_replace (atom_name: ABSTRACT_STRING; atom: PARSE_ATOM[C_])
  95. require
  96. atom_name /= Void
  97. atom /= Void
  98. do
  99. atoms.put(atom, atom_name.intern)
  100. ensure
  101. item(atom_name.intern) = atom
  102. end
  103. item (atom_name: ABSTRACT_STRING): PARSE_ATOM[C_]
  104. require
  105. not atom_name.is_empty
  106. has(atom_name)
  107. do
  108. Result := atoms.fast_reference_at(atom_name.intern)
  109. debug
  110. if Result = Void then
  111. log.trace.put_string(once "Unknown atom: ")
  112. log.trace.put_line(atom_name)
  113. log.trace.put_line(once "Known atoms:")
  114. log.trace.put_line(once "--8<--------")
  115. atoms.for_each(agent print_atom(?, ?))
  116. log.trace.put_line(once "-------->8--")
  117. breakpoint
  118. end
  119. end
  120. end
  121. out_in_tagged_out_memory
  122. do
  123. for_all_atoms(agent (atom: PARSE_ATOM[C_]) do atom.out_in_tagged_out_memory; tagged_out_memory.extend('%N') end)
  124. end
  125. pretty_print_on (stream: OUTPUT_STREAM)
  126. require
  127. stream.is_connected
  128. do
  129. for_all_atoms(agent {PARSE_ATOM[C_]}.pretty_print_on(stream))
  130. end
  131. for_all_atoms (action: PROCEDURE[TUPLE[PARSE_ATOM[C_]]])
  132. require
  133. action /= Void
  134. do
  135. atoms.for_each(action)
  136. end
  137. feature {}
  138. print_atom (v: PARSE_ATOM[C_]; k: FIXED_STRING)
  139. do
  140. log.trace.put_character('"')
  141. log.trace.put_string(k)
  142. log.trace.put_character('"')
  143. log.trace.put_string(once " => ")
  144. log.trace.put_line(v.out)
  145. end
  146. feature {PARSE_TABLE}
  147. atoms: LINKED_HASHED_DICTIONARY[PARSE_ATOM[C_], FIXED_STRING]
  148. feature {PARSER_FACET}
  149. add (name: ABSTRACT_STRING; atom: PARSE_ATOM[C_])
  150. require
  151. not has(name)
  152. atom.name = Void
  153. do
  154. atoms.add(atom, name.intern)
  155. atom.set(name, Current)
  156. ensure
  157. atoms.count = old atoms.count + 1
  158. atoms.last = atom
  159. end
  160. feature {}
  161. with_capacity, manifest_make (needed_capacity: INTEGER)
  162. do
  163. create atoms.with_capacity(needed_capacity)
  164. end
  165. manifest_put (index: INTEGER; name: ABSTRACT_STRING; atom: PARSE_ATOM[C_])
  166. require
  167. not has(name)
  168. atom.name = Void
  169. atoms.count = index
  170. do
  171. add(name, atom)
  172. ensure
  173. atom.name = name.intern
  174. atoms.count = old atoms.count + 1
  175. atoms.last = atom
  176. end
  177. manifest_semicolon_check: INTEGER 2
  178. end -- class PARSE_TABLE
  179. --
  180. -- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
  181. --
  182. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  183. -- of this software and associated documentation files (the "Software"), to deal
  184. -- in the Software without restriction, including without limitation the rights
  185. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  186. -- copies of the Software, and to permit persons to whom the Software is
  187. -- furnished to do so, subject to the following conditions:
  188. --
  189. -- The above copyright notice and this permission notice shall be included in
  190. -- all copies or substantial portions of the Software.
  191. --
  192. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  193. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  194. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  195. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  196. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  197. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  198. -- THE SOFTWARE.