[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How do you write an interactive interpreter?



Etienne M. Gagnon wrote:
> Pete Poulos wrote:
> > Is there a way to tell the parser to treat a production as a complete
> > "language" and stop reading the token stream without encountering an
> > EOF token or without throwing an exception?  If there is nothing for
> > this now, can I expect to see something like this in SableCC 4?
> 
> This is actually one of the main features of SableCC 4: you can
> explicitly define start parsing productions with expected ending (with
> or without EOF).

  SableCC 4 is all well and good, but what are we to do in the meantime?
Do you have an idea of when it will be ready for use?
  I think I have a general solution for 3.2:
1) read one line
2) try and parse it
3) if you got an AST then you are done
4) if you got an exception and the lexer is at EOF, read another line
and go back to (2)

  But it seems to me the parser has all the information it needs to
trivially [with the help of the developer] decide, on receipt of a
newline, whether a statement is complete or not. So I don't _like_ my
solution, but it seems to be the most elegant possible with 3.2 -
anything else involves writing your own parser or hacking sable's Parser
post-generation (I haven't been able to pull it off with anything
overridable).

  Anyway, it seems to work:

	public static Node read(BufferedReader in, PrintStream out) throws IOException, LexerException, ParserException {
		String line, stmt = "";
		Node ast = null;
		out.print("> ");
		line = in.readLine();
		while(line != null) {
			Lexer lexer;
			stmt = stmt + line + "\n";
			lexer = new Lexer(new PushbackReader(new StringReader(stmt), 128));
			try {
				ast = new Parser(lexer).parse();
				return ast;
			} catch(ParserException pe) {
				if(!(lexer.peek() instanceof EOF)) {
					throw pe;
				}
			}
			out.print("\t");
			line = in.readLine();
		}
		return ast;
	}			

  The out.prints aren't necessary, they just provide a prompt.

-Rowan

PS. Sorry for breaking the thread, I only subscribed today and can't
find a usable message-id or similar in any archive.