KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > python > core > parser


1 // Copyright (c) Corporation for National Research Initiatives
2
package org.python.core;
3
4 import org.python.parser.*;
5 import org.python.parser.ast.modType;
6 import java.io.*;
7
8 /**
9  * Facade for the classes in the org.python.parser package.
10  */

11
12 public class parser {
13     
14     private static IParserHost literalMkrForParser = new LiteralMakerForParser();
15
16     private parser() { ; }
17
18     static String JavaDoc getLine(BufferedReader reader, int line) {
19         if (reader == null)
20             return "";
21         try {
22             String JavaDoc text=null;
23             for(int i=0; i < line; i++) {
24                 text = reader.readLine();
25             }
26             return text;
27         } catch (IOException ioe) {
28             return null;
29         }
30     }
31
32
33     // if reader != null, reset it
34
public static PyException fixParseError(BufferedReader reader, Throwable JavaDoc t,
35                                      String JavaDoc filename)
36     {
37         if (reader != null) {
38             // System.err.println("resetting istream");
39
try {
40                 reader.reset();
41             } catch (IOException e) {
42                 reader = null;
43             }
44         }
45         
46         if (t instanceof ParseException) {
47             ParseException e = (ParseException)t;
48             Token tok = e.currentToken;
49             int col=0;
50             int line=0;
51             if (tok != null && tok.next != null) {
52                 col = tok.next.beginColumn;
53                 line = tok.next.beginLine;
54             }
55             String JavaDoc text=getLine(reader, line);
56             return new PySyntaxError(e.getMessage(), line, col,
57                                      text, filename);
58         }
59         if (t instanceof TokenMgrError) {
60             TokenMgrError e = (TokenMgrError)t;
61             boolean eofSeen = e.EOFSeen;
62
63             int col = e.errorColumn;
64             int line = e.errorLine;
65             //System.err.println("eof seen: "+eofSeen+", "+e.curChar+", "+col+
66
// ", "+line);
67
String JavaDoc text = getLine(reader, line);
68             if (eofSeen)
69                 col -= 1;
70             return new PySyntaxError(e.getMessage(), line, col,
71                                      text, filename);
72         }
73         else return Py.JavaError(t);
74     }
75
76
77     public static Node parse(String JavaDoc string, String JavaDoc kind) {
78         return parse(new StringBufferInputStream(string),
79                      kind, "<string>", null);
80     }
81
82     public static modType parse(InputStream istream, String JavaDoc kind,
83                                  String JavaDoc filename, CompilerFlags cflags)
84     {
85         BufferedReader bufreader = prepBufreader(istream, cflags);
86         
87         PythonGrammar g = new PythonGrammar(new ReaderCharStream(bufreader),
88                                             literalMkrForParser);
89
90         modType node = null;
91         try {
92             node = doparse(kind, cflags, g);
93         }
94         catch (Throwable JavaDoc t) {
95             throw fixParseError(bufreader, t, filename);
96         }
97         return node;
98     }
99
100     public static modType partialParse(String JavaDoc string, String JavaDoc kind,
101                                        String JavaDoc filename, CompilerFlags cflags,boolean stdprompt)
102     {
103         modType node = null;
104         //System.err.println(new PyString(string).__repr__().toString());
105

106         BufferedReader bufreader = prepBufreader(new StringBufferInputStream(string),
107                                                  cflags);
108         
109         PythonGrammar g = new PythonGrammar(new ReaderCharStream(bufreader),
110                                             literalMkrForParser);
111         
112         g.token_source.partial = true;
113         g.token_source.stdprompt = stdprompt;
114
115         try {
116             node = doparse(kind, cflags, g);
117         }
118         catch (Throwable JavaDoc t) {
119             /*
120              CPython codeop exploits that with CPython parser adding newlines
121              to a partial valid sentence move the reported error position,
122              this is not true for our parser, so we need a different approach:
123              we check whether all sentence tokens have been consumed or
124              the remaining ones fullfill lookahead expectations. See:
125              PythonGrammar.partial_valid_sentence (def in python.jjt)
126             */

127             
128             if (g.partial_valid_sentence(t)) {
129                 return null;
130             }
131             throw fixParseError(bufreader, t, filename);
132         }
133         return node;
134         
135         
136 // try {
137
// node = parse(new StringBufferInputStream(string),
138
// kind, filename, cflags, true);
139
// }
140
// catch (PySyntaxError e) {
141
// //System.out.println("e: "+e.lineno+", "+e.column+", "+
142
// // e.forceNewline);
143
// try {
144
// node = parse(new StringBufferInputStream(string+"\n"),
145
// kind, filename, cflags, true);
146
// }
147
// catch (PySyntaxError e1) {
148
// //System.out.println("e1: "+e1.lineno+", "+e1.column+
149
// // ", "+e1.forceNewline);
150
// if (e.forceNewline || !e1.forceNewline) throw e;
151
// }
152
// return null;
153
// }
154
// return node;
155
}
156
157     private static modType doparse(String JavaDoc kind, CompilerFlags cflags,
158                                    PythonGrammar g) throws ParseException
159     {
160         modType node = null;
161                
162         if (cflags != null)
163             g.token_source.generator_allowed = cflags.generator_allowed;
164         
165         if (kind.equals("eval")) {
166             node = g.eval_input();
167         }
168         else if (kind.equals("exec")) {
169             node = g.file_input();
170         }
171         else if (kind.equals("single")) {
172             node = g.single_input();
173         }
174         else {
175            throw Py.ValueError("parse kind must be eval, exec, " +
176                                "or single");
177         }
178         return node;
179     }
180
181     private static BufferedReader prepBufreader(InputStream istream,
182                                                 CompilerFlags cflags) {
183         int nbytes;
184         try {
185             nbytes = istream.available();
186         }
187         catch (IOException ioe1) {
188             nbytes = 10000;
189         }
190         if (nbytes <= 0)
191             nbytes = 10000;
192         if (nbytes > 100000)
193             nbytes = 100000;
194         
195         Reader reader = null;
196         try {
197             if (cflags != null && cflags.encoding != null) {
198                 reader = new InputStreamReader(istream, cflags.encoding);
199             }
200         } catch (UnsupportedEncodingException exc) { ; }
201         if (reader == null) {
202             reader = new InputStreamReader(istream);
203         }
204         
205         //if (Options.fixMacReaderBug);
206
reader = new FixMacReaderBug(reader);
207         
208         BufferedReader bufreader = new BufferedReader(reader);
209         
210         try {
211             bufreader.mark(nbytes);
212         } catch (IOException exc) { }
213         return bufreader;
214     }
215
216 }
217
218
219 /**
220  * A workaround for a bug in MRJ2.2's FileReader, where the value returned
221  * from read(b, o, l) sometimes are wrong.
222  */

223 class FixMacReaderBug extends FilterReader {
224     public FixMacReaderBug(Reader in) {
225         super(in);
226     }
227
228     public int read(char b[], int off, int len) throws IOException {
229         int l = super.read(b, off, len);
230         if (l < -1)
231             l += off;
232         return l;
233     }
234 }
235
236 class LiteralMakerForParser implements IParserHost {
237
238        public Object JavaDoc newLong(String JavaDoc s) {
239                return Py.newLong(s);
240        }
241
242        public Object JavaDoc newLong(java.math.BigInteger JavaDoc i) {
243                return Py.newLong(i);
244        }
245
246        public Object JavaDoc newFloat(double v) {
247                return Py.newFloat(v);
248        }
249
250        public Object JavaDoc newImaginary(double v) {
251                return Py.newImaginary(v);
252        }
253
254        public Object JavaDoc newInteger(int i) {
255                return Py.newInteger(i);
256        }
257
258        public String JavaDoc decode_UnicodeEscape(
259                String JavaDoc str, int start, int end, String JavaDoc errors, boolean unicode) {
260                        return PyString.decode_UnicodeEscape(str, start, end, errors, unicode);
261        }
262
263 }
Popular Tags