/src/lib/parse/parse_non_terminal.e
Specman e | 211 lines | 150 code | 21 blank | 40 comment | 5 complexity | 24e024b1fae342f8602dbec56821c178 MD5 | raw file
1-- This file is part of a Liberty Eiffel library. 2-- See the full copyright at the end. 3-- 4class PARSE_NON_TERMINAL 5 -- 6 -- A non-terminal meant to be put in a PARSE_TABLE. 7 -- 8 -- The only way to create a non-terminal is to use SmartEiffel's manifest notation. 9 -- 10 -- The structure of this notation is: 11 -- 12 -- {PARSE_NON_TERMINAL << rule, agent; 13 -- rule, agent; 14 -- . . . 15 -- rule, agent 16 -- >>} 17 -- 18 -- where each rule is a TRAVERSABLE[STRING] (with each String being the name of an atom of the 19 -- PARSE_TABLE), and each agent may either be Void or a PROCEDURE[TUPLE] called when reducing the 20 -- non-terminal. 21 -- 22 23inherit 24 PARSE_ATOM 25 redefine 26 copy, is_equal, out_in_tagged_out_memory 27 end 28 29insert 30 LOGGING 31 redefine 32 copy, is_equal, out_in_tagged_out_memory 33 end 34 35creation {ANY} 36 manifest_creation 37 38feature {ANY} 39 out_in_tagged_out_memory is 40 do 41 tagged_out_memory.extend('{') 42 parser_tree.out_in_tagged_out_memory 43 tagged_out_memory.extend('}') 44 end 45 46feature {PARSE_TABLE} 47 is_coherent: BOOLEAN is 48 do 49 Result := parser_tree.is_coherent 50 end 51 52 set_default_tree_builders (non_terminal_builder: PROCEDURE[TUPLE[FIXED_STRING, TRAVERSABLE[FIXED_STRING]]]; terminal_builder: PROCEDURE[TUPLE[FIXED_STRING, PARSER_IMAGE]]) is 53 do 54 if non_terminal_builder /= Void then 55 save_tree_builder_path 56 parser_tree.set_default_tree_builder(non_terminal_builder, tree_builder_path) 57 restore_tree_builder_path 58 end 59 end 60 61feature {DESCENDING_PARSER, PARSE_NT_NODE} 62 parse (buffer: MINI_PARSER_BUFFER; actions: COLLECTION[PARSE_ACTION]): TRISTATE is 63 do 64 Result := parser_tree.parse(buffer, actions) 65 if Result = yes then 66 buffer.set_last_error(Void) 67 debug ("parse") 68 log.trace.put_string(once "%T-->%Tnon-terminal ") 69 print_error_position(log.trace, buffer) 70 log.trace.put_character(' ') 71 log.trace.put_character('"') 72 log.trace.put_string(name) 73 log.trace.put_character('"') 74 log.trace.put_new_line 75 end 76 else 77 debug ("parse") 78 log.trace.put_string(once "** Expected non-terminal %"") 79 log.trace.put_string(name) 80 log.trace.put_string(once "%" ") 81 print_error_position(log.trace, buffer) 82 log.trace.put_new_line 83 end 84 end 85 end 86 87feature {ANY} 88 copy (other: like Current) is 89 do 90 name := other.name 91 parser_tree := other.parser_tree.twin 92 parser_tree.set_non_terminal(Current) 93 end 94 95 is_equal (other: like Current): BOOLEAN is 96 do 97 Result := name.is_equal(other.name) and then parser_tree.is_equal(other.parser_tree) 98 end 99 100 add (rule: TRAVERSABLE[FIXED_STRING]; action: PROCEDURE[TUPLE]) is 101 require 102 rule /= Void 103 do 104 parser_tree.add(rule, action) 105 end 106 107feature {PARSE_NON_TERMINAL} 108 parser_tree: PARSE_NT_NODE 109 110feature {} 111 tree_builder_path_used: FAST_ARRAY[FAST_ARRAY[FIXED_STRING]] is 112 once 113 create Result.make(0) 114 end 115 116 tree_builder_path_free: FAST_ARRAY[FAST_ARRAY[FIXED_STRING]] is 117 once 118 create Result.make(0) 119 end 120 121 tree_builder_path: FAST_ARRAY[FIXED_STRING] 122 123 save_tree_builder_path is 124 do 125 if tree_builder_path = Void then 126 tree_builder_path := free_tree_builder_path 127 elseif not tree_builder_path.is_empty then 128 tree_builder_path_used.add_last(tree_builder_path) 129 tree_builder_path := free_tree_builder_path 130 end 131 ensure 132 tree_builder_path.is_empty 133 ;(old (tree_builder_path /= Void and then not tree_builder_path.is_empty)) implies (tree_builder_path_used.last = old tree_builder_path) 134 ;(old (tree_builder_path /= Void and then not tree_builder_path.is_empty)) implies (tree_builder_path_used.count = old tree_builder_path_used.count + 1) 135 end 136 137 restore_tree_builder_path is 138 require 139 tree_builder_path.is_empty 140 do 141 if not tree_builder_path_used.is_empty then 142 tree_builder_path_free.add_last(tree_builder_path) 143 tree_builder_path := tree_builder_path_used.last 144 tree_builder_path_used.remove_last 145 end 146 ensure 147 tree_builder_path /= Void 148 ;(not old tree_builder_path_used.is_empty) implies (tree_builder_path = (old tree_builder_path_used.twin).last) 149 ;(not old tree_builder_path_used.is_empty) implies (tree_builder_path_used.count = old tree_builder_path_used.count - 1) 150 end 151 152 free_tree_builder_path: like tree_builder_path is 153 do 154 if tree_builder_path_free.is_empty then 155 create Result.make(0) 156 else 157 Result := tree_builder_path_free.last 158 tree_builder_path_free.remove_last 159 end 160 ensure 161 Result.is_empty 162 end 163 164feature {} 165 manifest_make (needed_capacity: INTEGER) is 166 do 167 create parser_tree.root(Current) 168 end 169 170 manifest_put (index: INTEGER; rule: TRAVERSABLE[ABSTRACT_STRING]; action: PROCEDURE[TUPLE[FIXED_STRING, TRAVERSABLE[FIXED_STRING]]]) is 171 require 172 rule /= Void 173 local 174 fixed_rule: FAST_ARRAY[FIXED_STRING] 175 i: INTEGER 176 do 177 create fixed_rule.with_capacity(rule.count) 178 from 179 i := rule.lower 180 until 181 i > rule.upper 182 loop 183 fixed_rule.add_last(rule.item(i).intern) 184 i := i + 1 185 end 186 parser_tree.add(fixed_rule, action) 187 end 188 189 manifest_semicolon_check: INTEGER is 2 190 191end -- class PARSE_NON_TERMINAL 192-- 193-- Copyright (c) 2009 by all the people cited in the AUTHORS file. 194-- 195-- Permission is hereby granted, free of charge, to any person obtaining a copy 196-- of this software and associated documentation files (the "Software"), to deal 197-- in the Software without restriction, including without limitation the rights 198-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 199-- copies of the Software, and to permit persons to whom the Software is 200-- furnished to do so, subject to the following conditions: 201-- 202-- The above copyright notice and this permission notice shall be included in 203-- all copies or substantial portions of the Software. 204-- 205-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 206-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 207-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 208-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 209-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 210-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 211-- THE SOFTWARE.