diff src/luan/interp/LuaParser.java @ 7:bca8fc5d928b

work on expressions git-svn-id: https://luan-java.googlecode.com/svn/trunk@8 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Tue, 20 Nov 2012 10:06:27 +0000
parents a315783c9524
children 8896068e0a4b
line wrap: on
line diff
--- a/src/luan/interp/LuaParser.java	Mon Nov 19 13:08:30 2012 +0000
+++ b/src/luan/interp/LuaParser.java	Tue Nov 20 10:06:27 2012 +0000
@@ -15,46 +15,108 @@
 public class LuaParser extends BaseParser<Object> {
 
 	Rule Target() {
-		return Sequence(ConstExpr(), EOI);
+		return Sequence(Spaces(), Expr(), EOI);
+	}
+
+	Rule Expr() {
+		return OrExpr();
+	}
+
+	Rule OrExpr() {
+		return Sequence(
+			AndExpr(),
+			ZeroOrMore( "or", Spaces(), AndExpr(), push( new OrExpr((Expr)pop(1),(Expr)pop()) ) )
+		);
+	}
+
+	Rule AndExpr() {
+		return Sequence(
+			RelExpr(),
+			ZeroOrMore( "and", Spaces(), RelExpr(), push( new AndExpr((Expr)pop(1),(Expr)pop()) ) )
+		);
+	}
+
+	Rule RelExpr() {
+		return Sequence(
+			SumExpr(),
+			ZeroOrMore(
+				FirstOf(
+					Sequence( "==", Spaces(), SumExpr(), push( new EqExpr((Expr)pop(1),(Expr)pop()) ) ),
+					Sequence( "~=", Spaces(), SumExpr(), push( new NotExpr(new EqExpr((Expr)pop(1),(Expr)pop())) ) )
+				)
+			)
+		);
 	}
 
-	Rule ConstExpr() {
+	Rule SumExpr() {
+		return Sequence(
+			TermExpr(),
+			ZeroOrMore(
+				FirstOf(
+					Sequence( '+', Spaces(), TermExpr(), push( new AddExpr((Expr)pop(1),(Expr)pop()) ) ),
+					Sequence( '-', Spaces(), TermExpr(), push( new SubExpr((Expr)pop(1),(Expr)pop()) ) )
+				)
+			)
+		);
+	}
+
+	Rule TermExpr() {
 		return Sequence(
-			Const(),
+			UnaryExpr(),
+			ZeroOrMore(
+				FirstOf(
+					Sequence( '*', Spaces(), UnaryExpr(), push( new MulExpr((Expr)pop(1),(Expr)pop()) ) ),
+					Sequence( '/', Spaces(), UnaryExpr(), push( new DivExpr((Expr)pop(1),(Expr)pop()) ) ),
+					Sequence( '%', Spaces(), UnaryExpr(), push( new ModExpr((Expr)pop(1),(Expr)pop()) ) )
+				)
+			)
+		);
+	}
+
+	Rule UnaryExpr() {
+		return FirstOf(
+			Sequence( '#', Spaces(), SingleExpr(), push( new LenExpr((Expr)pop()) ) ),
+			Sequence( '-', Spaces(), SingleExpr(), push( new UnmExpr((Expr)pop()) ) ),
+			Sequence( "not", Spaces(), SingleExpr(), push( new NotExpr((Expr)pop()) ) ),
+			SingleExpr()
+		);
+	}
+
+	Rule SingleExpr() {
+		return FirstOf(
+			Sequence( '(', Spaces(), Expr(), ')', Spaces() ),
+			LiteralExpr()
+		);
+	}
+
+	Rule LiteralExpr() {
+		return Sequence(
+			Literal(), Spaces(),
 			push(new ConstExpr(pop()))
 		);
 	}
 
-	Rule Const() {
+	Rule Literal() {
 		return FirstOf(
-			NilConst(),
-			BooleanConst(),
-			NumberConst(),
-			StringConst()
+			NilLiteral(),
+			BooleanLiteral(),
+			NumberLiteral(),
+			StringLiteral()
 		);
 	}
 
-	Rule NilConst() {
-		return Sequence(
-			String("nil"),
-			push(null)
+	Rule NilLiteral() {
+		return Sequence( "nil", push(null) );
+	}
+
+	Rule BooleanLiteral() {
+		return FirstOf(
+			Sequence( "true", push(true) ),
+			Sequence( "false", push(false) )
 		);
 	}
 
-	Rule BooleanConst() {
-		return FirstOf(
-			Sequence(
-				String("true"),
-				push(true)
-			),
-			Sequence(
-				String("false"),
-				push(false)
-			)
-		);
-	}
-
-	Rule NumberConst() {
+	Rule NumberLiteral() {
 		return Sequence(
 			Number(),
 			push(new LuaNumber((Double)pop()))
@@ -79,17 +141,10 @@
 		return FirstOf(
 			Sequence(
 				Int(),
-				Optional(
-					Ch('.'),
-					Optional(Int())
-				),
+				Optional( '.', Optional(Int()) ),
 				NumberExp()
 			),
-			Sequence(
-				Ch('.'),
-				Int(),
-				NumberExp()
-			)
+			Sequence( '.', Int(), NumberExp() )
 		);
 	}
 
@@ -116,7 +171,7 @@
 		return CharRange('0', '9');
 	}
 
-	Rule StringConst() {
+	Rule StringLiteral() {
 		return FirstOf(
 			QuotedString('"'),
 			QuotedString('\'')
@@ -125,7 +180,7 @@
 
 	Rule QuotedString(char quote) {
 		return Sequence(
-			Ch(quote),
+			quote,
 			push(new StringBuffer()),
 			ZeroOrMore(
 				FirstOf(
@@ -136,23 +191,42 @@
 					EscSeq()
 				)
 			),
-			Ch(quote),
+			quote,
 			push(((StringBuffer)pop()).toString())
 		);
 	}
 
 	Rule EscSeq() {
 		return Sequence(
-			Ch('\\'),
+			'\\',
 			FirstOf(
-				Sequence( Ch('b'), append('\b') ),
-				Sequence( Ch('f'), append('\f') ),
-				Sequence( Ch('n'), append('\n') ),
-				Sequence( Ch('r'), append('\r') ),
-				Sequence( Ch('t'), append('\t') ),
-				Sequence( Ch('\\'), append('\\') ),
-				Sequence( Ch('"'), append('"') ),
-				Sequence( Ch('\''), append('\'') )
+				Sequence( 'a', append('\u0007') ),
+				Sequence( 'b', append('\b') ),
+				Sequence( 'f', append('\f') ),
+				Sequence( 'n', append('\n') ),
+				Sequence( 'r', append('\r') ),
+				Sequence( 't', append('\t') ),
+				Sequence( 'v', append('\u000b') ),
+				Sequence( '\\', append('\\') ),
+				Sequence( '"', append('"') ),
+				Sequence( '\'', append('\'') ),
+				Sequence(
+					'x',
+					Sequence( HexDigit(), HexDigit() ),
+					append( (char)Integer.parseInt(match(),16) )
+				),
+				Sequence(
+					Sequence(
+						Digit(),
+						Optional(
+							Digit(),
+							Optional(
+								Digit()
+							)
+						)
+					),
+					append( (char)Integer.parseInt(match()) )
+				)
 			)
 		);
 	}
@@ -163,6 +237,10 @@
 		return true;
 	}
 
+	public Rule Spaces() {
+		return ZeroOrMore(AnyOf(" \t"));
+	}
+
 	// for testing
 	public static void main(String[] args) throws Exception {
 		LuaParser parser = Parboiled.createParser(LuaParser.class);