well, the parser is quite simple ...
first you will need quite a lot of stuff (i'll omit constructors, since i guess you can write them on your own):
expressions (output):
class Expression {}
class Operation extends Expression {
public var operand1:Expression;
public var operator:String;
public var operand2:Expression;
}
class Atom extends Expression {
public var ident:String;
}
tokens (intermediary format):
class Token {
public var source:String;
public var pos:uint;
}
class Identiefier extends Token {
public var ident:String;
}
class OpenParenthesis extends Token {}
class CloseParenthesis extends Token {}
class Operator extends Token {
public var operator:String;
}
class Eof extends Token {}
and a tokenizer, that should implement this interface
interface TokenStream {
function read():Token;
}
i guess you'll figure out yourself how to tokenize ...
so the way is source --(tokenizer)--> tokens --(parser)--> expressions ...
and here the parsing routine, with a little helper:
function parse(t:TokenStream):Expression {
var tk:Token = t.read();
switch ((tk as Object).constructor) {//this is a really weird thing about AS3 ... need to cast to object, before you can access the constructor
case OpenParanthesis:
var e1:Expression = parse(t);
tk = t.read();
switch ((tk as Object).constructor) {
case CloseParenthesis:
return e1;
case Operator:
var op:String = (tk as Operator).operator;
var e2:Expression = parse(t);
tk = t.read();
if (tk is CloseParenthesis)
return new Operation(e1,op,e2);
else
unexpected(tk);
}
else
unexpected(tk);
break;
case Identifier:
return new Atom((tk as Identifier).ident);
default:
unexpected(tk);
}
}
function unexpected(tk:Token) {
throw "unexpected token "+tk.source+" at position "+tk.pos;
}
this is not a particularly good parser, but it shows the bare fundamentals of parsing routines ... well, actually, i didn't check the implementation, but it should work ... it is very primitive and unpermissive ... things like operator precedence etc. are completely missing, and so on ... but if you want that, have a go at it ...
btw. using haXe with enums, the whole code would look much shorter and much more beautiful ... you may want to have a look at it ...
good luck then ... ;)