KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > core > parsers > acc > AccScanner


1 /*
2   Copyright (C) 2001-2003 Laurent Martelli <laurent@aopsys.com>
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12   GNU Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public
15   License along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17   USA */

18
19 package org.objectweb.jac.core.parsers.acc;
20
21
22 import java.io.FileInputStream JavaDoc;
23 import java.io.FileNotFoundException JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.io.InputStreamReader JavaDoc;
27 import java.io.Reader JavaDoc;
28 import java.io.StringWriter JavaDoc;
29 import java.net.MalformedURLException JavaDoc;
30 import java.net.URL JavaDoc;
31 import java.util.Set JavaDoc;
32 import java_cup.runtime.Scanner;
33 import java_cup.runtime.Symbol;
34 import org.apache.log4j.Logger;
35 import org.objectweb.jac.util.PushbackReader;
36
37 public class AccScanner implements Scanner {
38     static Logger logger = Logger.getLogger("acc.scanner");
39     static Logger loggerParser = Logger.getLogger("acc.parser");
40
41     PushbackReader input;
42     String JavaDoc streamName;
43     int line;
44     boolean bol; // beginning of line
45
boolean previousBol; // beginning of line
46

47     AccScanner include = null;
48     Set JavaDoc blockKeywords;
49
50     public AccScanner(Reader JavaDoc input, String JavaDoc streamName, Set JavaDoc blockKeywords) {
51         logger.debug("FileInputStream("+streamName+")");
52         this.input = new PushbackReader(input,2);
53         this.streamName = streamName;
54         this.line = 1;
55         this.bol = true;
56         this.blockKeywords = blockKeywords;
57         //System.out.println(streamName+":INIT");
58
}
59
60     public AccScanner(String JavaDoc streamName, Set JavaDoc blockKeywords)
61         throws IOException JavaDoc
62     {
63         InputStream JavaDoc inputStream = null;
64         try {
65             logger.debug("FileInputStream("+streamName+")");
66             inputStream = new FileInputStream JavaDoc(streamName);
67         } catch ( FileNotFoundException JavaDoc e ) {
68             try {
69                 logger.debug("getResourceAsStream("+streamName+")");
70                 inputStream = getClass().getClassLoader().getResourceAsStream(streamName);
71             } catch (Exception JavaDoc e2 ) {
72                 logger.debug("new URL("+streamName+")");
73                 try {
74                     URL JavaDoc url = new URL JavaDoc(streamName);
75                     inputStream = url.openStream();
76                 } catch (MalformedURLException JavaDoc e3) {
77                     e3.printStackTrace();
78                 }
79             }
80         }
81
82         if (inputStream==null)
83             throw new FileNotFoundException JavaDoc("file not found : "+streamName);
84
85         this.input = new PushbackReader(new InputStreamReader JavaDoc(inputStream),2);
86         this.streamName = streamName;
87         this.line = 1;
88         this.bol = true;
89         this.blockKeywords = blockKeywords;
90
91         // System.out.println(streamName+":INIT");
92
}
93
94     public void printState() {
95         logger.error(getLine());
96         if (include!=null)
97             include.printState();
98     }
99
100     protected boolean isEof(int c) {
101         return c==-1 || c==65535;
102     }
103
104     public Symbol next_token() throws java.lang.Exception JavaDoc
105     {
106         if (include!=null) {
107             Symbol token = include.next_token();
108             if (token.sym != -1) {
109                 return token;
110             }
111             include = null;
112         }
113
114         boolean quoted = false;
115         int c = input.read();
116         while (true) {
117             // skip white spaces and CR
118
while (c==' ' || c=='\t' || c=='\n' || c=='\r') {
119                 //System.out.println(streamName+":"+line+":WHITESPACE");
120
if (c=='\n' || c=='\r') {
121                     //System.out.println(streamName+":"+line+":NEWLINE1");
122
line++;
123                     bol = true;
124                     if (c=='\r') {
125                         c = input.read();
126                         if (c != '\n')
127                             input.unread(c);
128                     }
129                 }
130                 c = input.read();
131             }
132             // skip comments
133
if (c=='/') {
134                 int ahead = input.read();
135                 if (ahead=='/') {
136                     // c++-style comments
137
//System.out.println(streamName+":"+line+":C++ COMMENT");
138
c = input.read();
139                     while (c!='\n' && c!='\r' && c!=-1) {
140                         c = input.read();
141                     }
142                     continue;
143                 } if (ahead=='*') {
144                     // c-style comments
145
//System.out.println(streamName+":"+line+":C COMMENT");
146
int prev = c;
147                     c = input.read();
148                     boolean state = false;
149                     while (!(state && c=='/') && c!=-1) {
150                         if ((c=='\n' && prev!='\r') || c=='\r') line++;
151                         state = (c=='*');
152                         prev = c;
153                         c = input.read();
154                     }
155                     if (c==-1) {
156                         logger.error("unclosed comment");
157                         printState();
158                         break;
159                     }
160                     c = input.read();
161                     continue;
162                
163                 } else {
164                     input.unread(ahead);
165                     break;
166                 }
167             }
168             break;
169         }
170
171         int start = input.getPosition()-1;
172         Symbol token = null;/*new Symbol(AccSymbols.error);*/
173
174         //System.out.println("Testing char `"+c+"' = `"+(char)c+"'");
175
switch (c) {
176             case -1:
177             case 65535:
178                 return null;
179                 //token = new Symbol(AccSymbols.EOF);
180
//System.out.println(streamName+":TOKEN "+token.sym+"["+token.value+"]");
181
//break;
182
case '{':
183                 token = new Symbol(AccSymbols.LBRACE,start,start,"{");
184                 break;
185             case '}':
186                 token = new Symbol(AccSymbols.RBRACE,start,start,"}");
187                 break;
188             case ',':
189                 token = new Symbol(AccSymbols.COMMA,start,start,",");
190                 break;
191                 // when -1 is unread(), it becomes \uFFFF
192
case ';':
193                 token = new Symbol(AccSymbols.EOL,start,start,";");
194                 break;
195             case '/':
196                 token = new Symbol(AccSymbols.EOL,start,start,"/");
197                 break;
198             case '"':
199                 // quoted string
200
{
201                     quoted = true;
202                     StringWriter JavaDoc value = new StringWriter JavaDoc();
203                     c = input.read();
204                     boolean escaped = false;
205                     if (c=='\\') {
206                         escaped = true;
207                         c=readEscaped(input.read());
208                     }
209                     while ((c!='"' || escaped) && !isEof(c)) {
210                         value.write(c);
211                         c = input.read();
212                         if (c=='\n')
213                             line++;
214                         escaped = false;
215                         if (c=='\\') {
216                             c=readEscaped(input.read());
217                             escaped = true;
218                         }
219                     }
220                     //System.out.println("value="+value);
221
String JavaDoc str = value.toString();
222                     token = new Symbol(AccSymbols.ATOMIC_VALUE,
223                                        start,start+str.length()-1,str);
224                 }
225                 break;
226             default:
227                 {
228                     StringWriter JavaDoc value = new StringWriter JavaDoc();
229                     String JavaDoc delim="/{},; \t\n\r";
230                     while (delim.indexOf(c)==-1 && c!=-1) {
231                         value.write(c);
232                         c = input.read();
233                     }
234                     input.unread(c);
235                     //System.out.println("value="+value);
236
String JavaDoc str = value.toString();
237                     token = new Symbol(AccSymbols.ATOMIC_VALUE,
238                                        start,start+str.length()-1,str);
239                 }
240         }
241
242         previousBol = bol;
243
244         if (bol && token.sym == AccSymbols.ATOMIC_VALUE && token.value.equals("include")) {
245             bol = false;
246             String JavaDoc filename = (String JavaDoc)next_token().value;
247             //System.out.println(streamName+":INCLUDE("+filename+")");
248
include = new AccScanner(filename,blockKeywords);
249             return next_token();
250         }
251         if (!quoted && token.sym == AccSymbols.ATOMIC_VALUE &&
252             ( token.value.equals("class") ||
253               token.value.equals("member") ||
254               token.value.equals("method") ||
255               token.value.equals("attribute") ||
256               token.value.equals("block") ||
257               blockKeywords.contains(token.value) ) )
258         {
259             token.sym = AccSymbols.CLASS;
260             //System.out.println(streamName+":TOKEN block");
261
}
262         if (!quoted && token.sym == AccSymbols.ATOMIC_VALUE &&
263             token.value.equals("import")) {
264             token.sym = AccSymbols.IMPORT;
265         }
266         if (!quoted && token.sym == AccSymbols.ATOMIC_VALUE &&
267             token.value.equals("null")) {
268             token.value = null;
269         }
270         token.left = start;
271         if (token.value instanceof String JavaDoc)
272             token.right = start + ((String JavaDoc)token.value).length() - 1;
273         if (quoted)
274             token.right += 2;
275
276         //System.out.println(streamName+":TOKEN "+token.sym+"["+token.value+"]");
277
loggerParser.debug("read token "+token+" = "+token.value);
278         bol = false;
279         return token;
280     }
281
282     /**
283      * Read a char from input, possibly escaped by '\'
284      */

285     int readEscaped(int c) throws IOException JavaDoc
286     {
287         switch (c) {
288             case 'n':
289                 return '\n';
290             case 'r':
291                 return '\r';
292             case 't':
293                 return '\t';
294             default:
295                 return c;
296         }
297     }
298
299     /**
300      * Return the current line number
301      */

302     public String JavaDoc getLine() {
303         if (include!=null)
304             return include.getLine();
305         else
306             return streamName+":"+(previousBol?line-1:line);
307     }
308
309 }
310
Popular Tags