Posted By:
Ian_Warner
Posted On:
Tuesday, June 8, 2004 04:14 AM
I've written a grammar for parsing CSS. In my application, I need to parse declaration lists such as the value of @style in xhtml. eg. I have a utility class that reuses the Lexer/Parser using a LexerSharedInputState and MutableStringReader (see code snippet below). final class BrowserUtilities { ... private static MutableStringReader stringReader = new MutableStringReader(); private static LexerSharedInputState inputState = new LexerSharedInputState(stringReader); private static CSS2Lexer cssLexer = new CSS2Lexer(inputState); private static CSS2Parser cssParser = new CSS2Parser(cssLexer); private static CSS2TreeParser cs
More>>
I've written a grammar for parsing CSS. In my application, I need to parse declaration lists such as the value of @style in xhtml. eg.
I have a utility class that reuses the Lexer/Parser using a
LexerSharedInputState
and
MutableStringReader
(see code snippet below).
final class BrowserUtilities {
...
private static MutableStringReader stringReader = new MutableStringReader();
private static LexerSharedInputState inputState = new LexerSharedInputState(stringReader);
private static CSS2Lexer cssLexer = new CSS2Lexer(inputState);
private static CSS2Parser cssParser = new CSS2Parser(cssLexer);
private static CSS2TreeParser cssTreeParser = new CSS2TreeParser();
...
static void setCssText(String source, StyleImpl style) {
synchronized (stringReader) {
try {
stringReader.reset(source);
inputState.reset();
cssParser.compileDeclarationList();
style.clearProperties();
cssTreeParser.declList(cssParser.getAST(), style);
}
catch (antlr.ANTLRException ex) {
ex.printStackTrace();
throw new StyleException("Invalid CSS text");
}
}
}
}
class MutableStringReader extends Reader {
private String string = "";
private int pos = 0;
private int slen = 0;
MutableStringReader() { }
MutableStringReader(String initial) {
this.string = initial;
slen = string.length();
}
void reset(String s) {
string = s;
pos = 0;
slen = string.length();
}
public void close() throws IOException { }
public int read(char[] cbuf, int off, int len) throws IOException {
if (pos >= slen) return -1;
int total = 0;
slurp:
for (; len>0; --len, ++off) {
cbuf[off] = string.charAt(pos);
++total;
++pos;
if (pos >= slen) break slurp;
}
return total;
}
}
This technique works fine until an invalid
source
value is passed to
setCssText(String, StyleImpl)
. This results in
antlr.NoViableAltException
and
antlr.MismatchedTokenException
exceptions being thrown which seems to invalidate the state of the
Parser
instance. Although the
MutableStringReader
and
LexerSharedInputState
get reset upon each invocation of the method, the
Parser
seems 'stuck' on the invalid input from the previous call.
How do I reset the state of the
Parser
?
Hope the question seems clear and thanks in advance.
<<Less