-- This file is part of SmartEiffel The GNU Eiffel Compiler. -- Copyright (C) 1994-2002 LORIA - INRIA - U.H.P. Nancy 1 - FRANCE -- Dominique COLNET and Suzanne COLLIN - SmartEiffel@loria.fr -- http://SmartEiffel.loria.fr -- 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. -- deferred class PARSER -- -- To share some features amongs parsers (actually the -- EIFFEL_PARSER and the ACE parser). -- inherit GLOBALS 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." em20: STRING is "Explicit creation/create type mark must not be anchored." 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." em33: STRING is "TUPLE 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 ascii code." em39: STRING is "Bad (empty ?) ascii code." em40: STRING is "Three digit is enought for an ascii code." 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.)" end -- PARSER