File: parser.e

package info (click to toggle)
smarteiffel 1.1-11
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 12,288 kB
  • ctags: 40,785
  • sloc: ansic: 35,791; lisp: 4,036; sh: 1,783; java: 895; ruby: 613; python: 209; makefile: 115; csh: 78; cpp: 50
file content (290 lines) | stat: -rw-r--r-- 8,093 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
-- This file is part of SmartEiffel The GNU Eiffel Compiler Tools and Libraries
--
-- SmartEiffel is  free software;  you can redistribute it and/or  modify it
-- under  the terms of the  GNU General Public License, as published by  the
-- Free Software Foundation; either version 2, or (at your option) any later
-- version.
-- SmartEiffel is distributed in the hope that it will be useful but WITHOUT 
-- ANY WARRANTY;  without  even the implied warranty  of MERCHANTABILITY  or
-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-- more details.  You should have received a copy of  the GNU General Public
-- License along with SmartEiffel;  see the file COPYING.  If not,  write to
-- the Free Software Foundation,  Inc., 59 Temple Place - Suite 330,  Boston, 
-- MA 02111-1307, USA.
--
-- Copyright(C) 1994-2002: INRIA - LORIA (INRIA Lorraine) - ESIAL U.H.P.
--			   - University of Nancy 1 - FRANCE
-- Copyright(C) 2003:      INRIA - LORIA (INRIA Lorraine) - I.U.T. Charlemagne
--			   - University of Nancy 2 - FRANCE
--
--		 Dominique COLNET, Suzanne COLLIN, Olivier ZENDRA,
--			   Philippe RIBET, Cyril ADRIAN
--
-- http://SmartEiffel.loria.fr - SmartEiffel@loria.fr
--
deferred class PARSER
   --
   -- To share some features amongs parsers (actually the
   -- EIFFEL_PARSER and the ACE parser).
   --
inherit
   GLOBALS
   VISITABLE

feature {PARSER_VISITOR}

   accept(visitor: PARSER_VISITOR) is
      deferred
      end

feature {NONE}

   line, column: INTEGER
	 -- Current `line' number and current `column' number.

   current_line: STRING
	 -- Current line string of `text'.

   cc: CHARACTER
	 -- Current character in the `current_line'.

   pos(l, c: INTEGER): POSITION is
	 -- Initialize a new one at line `l' and column `c'.
      require
	 l >= 1; c >= 1
      deferred
      end

   end_of_text: CHARACTER is '%/0/'; -- Flag of the end of the `text'.

   last_comment: COMMENT
	 -- Void or waiting comment.

   drop_comments: BOOLEAN
	 -- When objects COMMENT are not necessary.

   skip_comments is
	 -- Skip separators and comments if any. Unless `drop_comments',
	 -- comments are stored in `last_comment'.
      local
	 sp: POSITION; stop: BOOLEAN
      do
	 from
	 until
	    stop
	 loop
	    inspect
	       cc
	    when ' ','%T','%N' then
	       next_char
	    when '-' then
	       next_char
	       if cc = '-' then
		  if drop_comments then
		     if line = parser_buffer.count then
			cc := end_of_text
			stop := true
		     else
			line := line + 1
			column := 1
			current_line := parser_buffer.item(line)
			if current_line.count = 0 then
			   cc := '%N'
			else
			   cc := current_line.first
			end
		     end
		  else
		     from
			sp := pos(line,column - 1)
			next_char
			lcs.clear
		     until
			cc = '%N'
		     loop
			lcs.extend(cc)
			next_char
		     end
		     if last_comment = Void then
			!!last_comment.make(sp,lcs.twin)
		     else
			last_comment.add_last(lcs.twin)
		     end
		  end
	       else
		  cc := '-'
		  column := column - 1
		  stop := true
	       end
	    else
	       stop := true
	    end
	 end
      end

   next_char is
      do
	 if column < current_line.count then
	    column := column + 1
	    cc := current_line.item(column)
	 elseif column = current_line.count then
	    column := column + 1
	    cc := '%N'
	 elseif line = parser_buffer.count then
	    cc := end_of_text
	 else
	    line := line + 1
	    column := 1
	    current_line := parser_buffer.item(line)
	    if current_line.count = 0 then
	       cc := '%N'
	    else
	       cc := current_line.first
	    end
	 end
      end

   start_line, start_column: INTEGER
	 -- To store beginning position of : `a_keyword', `a_integer',
	 -- `a_real', `skip1', `skip2' and `skip1unless2'.

   a_keyword(keyword: STRING): BOOLEAN is
	 -- Look for a `keyword' beginning strictly at current position, then,
	 -- `skip_comment' is automatically called. A keyword is never followed
	 -- by a character of this set: {'A'..'Z','a'..'z','0'..'9','_'}.
      require
	 keyword.count >= 1
	 not keyword.has('%N')
      local
	 c, i, j: INTEGER
      do
	 i := column
	 c := keyword.count
	 if current_line.count - i + 1 >= c then
	    from
	       start_line := line
	       start_column := i
	       j := 1
	    until
	       c <= 0
	    loop
	       if current_line.item(i).same_as(keyword.item(j)) then
		  i := i + 1
		  j := j + 1
		  c := c - 1
	       else
		  c := -1
	       end
	    end
	 end
	 if c = 0 then
	    if i > current_line.count then
	       Result := true
	       cc := '%N'
	       column := i
	       skip_comments
	    else
	       inspect
		  current_line.item(i)
	       when ' ','%T','-' then
		  Result := true
		  cc := current_line.item(i)
		  column := i
		  skip_comments
	       when 'a'..'z','A'..'Z','0'..'9','_' then
	       else
		  Result := true
		  cc := current_line.item(i)
		  column := i
	       end
	    end
	 end
      end

   skip1(char: CHARACTER): BOOLEAN is
      do
	 if char = cc then
	    start_line := line
	    start_column := column
	    Result := true
	    next_char
	    skip_comments
	 end
      end

   fcp(msg: STRING) is
	 -- Fatal error at current position.
      do
	 error_handler.add_position(current_position)
	 error_handler.append(msg)
	 error_handler.print_as_fatal_error
      end

   wcp(msg: STRING) is
	 -- Warning at current position.
      do
	 warning(current_position,msg)
      end

   current_position: POSITION is
      do
	 Result := pos(line,column)
      end

   lcs: STRING is
	 -- Last Comment String.
      once
	 !!Result.make(80)
      end

   tmp_name: TMP_NAME
	 -- The temporary buffer for some name.

   em1 : STRING is "Underscore in fractionnal part must group 3 digits."
   em2 : STRING is "Feature name expected."
   em3 : STRING is "Index value expected (%"indexing ...%")."
   em4 : STRING is "Error in inspect."
   em5 : STRING is "Added %",%"."
   em6 : STRING is "Added %";%"."
   em7 : STRING is "Unexpected comma (deleted)."
   em8 : STRING is "Unexpected new line in manifest string."
   em9 : STRING is "Underscore in number must group 3 digits."
   em10: STRING is "Bad character constant."
   em11: STRING is "Bad clients list."
   em12: STRING is "Deleted extra coma."
   em13: STRING is "Deleted extra separator."
   em14: STRING is "Class name should use only uppercase letters."
   em15: STRING is "Name of the current class expected."
   em16: STRING is "Type mark expected."
   em17: STRING is "Unexpected character."
   em18: STRING is "Useless keyword deleted."

   em21: STRING is "A formal argument is not a writable variable."
   em22: STRING is "Bad creation/create (writable expected)."
   em23: STRING is "Bad creation/create (procedure name expected)."
   em24: STRING is "Deleted extra semi-colon."
   em25: STRING is "Identifier should use only lowercase letters."
   em26: STRING is "Same identifier appears twice (local/formal)."
   em27: STRING is "Added %"(%"."
   em28: STRING is "Added %")%"."
   em29: STRING is "Added %":%"."
   em30: STRING is "Expected %"[%" (to start generic argument list)."
   em31: STRING is "Expected %"]%" (to finish generic argument list)."
   em32: STRING is "Type mark expected."
   em34: STRING is "Bad agent (call expected)."
   em35: STRING is "Empty generic list (deleted)."
   em36: STRING is "Closing %"}%" expected."
   em37: STRING is "Unknown special character."
   em38: STRING is "Unexpected character in decimal ascii code."
   em39: STRING is "Bad (empty?) ascii code."
   em40: STRING is "Decimal CHARACTER code out of range."
   em41: STRING is "Error inside multi-line manifest string."
   em42: STRING is "Extra blank or tab character removed in multi-line %
                   %manifest string."
   em43: STRING is "Invalid free operator (the last character must be %
		   %a member of this +-*/\=<>@#|& character list.)."
   em44: STRING is "Invalid free operator. (This character cannot be used.)"
   em45: STRING is "Unexpected character in hexadecimal ascii code."
   em46: STRING is "Unexpected character in hexadecimal unicode."
      
end -- PARSER