changeset 6:a315783c9524

more parsing git-svn-id: https://luan-java.googlecode.com/svn/trunk@7 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Mon, 19 Nov 2012 13:08:30 +0000
parents 9ef0fd711101
children bca8fc5d928b
files src/luan/interp/LuaParser.java
diffstat 1 files changed, 94 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/interp/LuaParser.java	Mon Nov 19 09:49:06 2012 +0000
+++ b/src/luan/interp/LuaParser.java	Mon Nov 19 13:08:30 2012 +0000
@@ -8,66 +8,74 @@
 import org.parboiled.support.ParsingResult;
 import org.parboiled.errors.ErrorUtils;
 import luan.Lua;
+import luan.LuaNumber;
 import luan.LuaState;
 
 
 public class LuaParser extends BaseParser<Object> {
 
-	public Rule Target() {
+	Rule Target() {
 		return Sequence(ConstExpr(), EOI);
 	}
 
-	public Rule ConstExpr() {
+	Rule ConstExpr() {
 		return Sequence(
 			Const(),
 			push(new ConstExpr(pop()))
 		);
 	}
 
-	public Rule Const() {
+	Rule Const() {
 		return FirstOf(
 			NilConst(),
-			BinaryConst(),
-			NumberConst()
+			BooleanConst(),
+			NumberConst(),
+			StringConst()
 		);
 	}
 
-	public Rule NilConst() {
+	Rule NilConst() {
 		return Sequence(
 			String("nil"),
 			push(null)
 		);
 	}
 
-	public Rule BinaryConst() {
+	Rule BooleanConst() {
 		return FirstOf(
-			TrueConst(),
-			FalseConst()
-		);
-	}
-
-	public Rule TrueConst() {
-		return Sequence(
-			String("true"),
-			push(true)
+			Sequence(
+				String("true"),
+				push(true)
+			),
+			Sequence(
+				String("false"),
+				push(false)
+			)
 		);
 	}
 
-	public Rule FalseConst() {
+	Rule NumberConst() {
 		return Sequence(
-			String("false"),
-			push(false)
+			Number(),
+			push(new LuaNumber((Double)pop()))
 		);
 	}
 
-	public Rule NumberConst() {
-		return Sequence(
-			Number(),
-			push(Double.parseDouble(match()))
+	Rule Number() {
+		return FirstOf(
+			Sequence(
+				IgnoreCase("0x"),
+				OneOrMore(HexDigit()),
+				push((double)Long.parseLong(match(),16))
+			),
+			Sequence(
+				DecNumber(),
+				push(Double.parseDouble(match()))
+			)
 		);
 	}
 
-	public Rule Number() {
+	Rule DecNumber() {
 		return FirstOf(
 			Sequence(
 				Int(),
@@ -85,7 +93,7 @@
 		);
 	}
 
-	public Rule NumberExp() {
+	Rule NumberExp() {
 		return Optional(
 			IgnoreCase('e'),
 			Optional(AnyOf("+-")),
@@ -93,19 +101,73 @@
 		);
 	}
 
-    Rule Int() {
-        return OneOrMore(Digit());
-    }
+	Rule Int() {
+		return OneOrMore(Digit());
+	}
+
+	Rule HexDigit() {
+		return FirstOf(
+			Digit(),
+			AnyOf("abcdefABCDEF")
+		);
+	}
+
+	Rule Digit() {
+		return CharRange('0', '9');
+	}
+
+	Rule StringConst() {
+		return FirstOf(
+			QuotedString('"'),
+			QuotedString('\'')
+		);
+	}
 
-    Rule Digit() {
-        return CharRange('0', '9');
-    }
+	Rule QuotedString(char quote) {
+		return Sequence(
+			Ch(quote),
+			push(new StringBuffer()),
+			ZeroOrMore(
+				FirstOf(
+					Sequence(
+						NoneOf("\\\n"+quote),
+						append(matchedChar())
+					),
+					EscSeq()
+				)
+			),
+			Ch(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('\'') )
+			)
+		);
+	}
+
+	boolean append(char ch) {
+		StringBuffer sb = (StringBuffer)peek();
+		sb.append(ch);
+		return true;
+	}
 
 	// for testing
 	public static void main(String[] args) throws Exception {
 		LuaParser parser = Parboiled.createParser(LuaParser.class);
 		while( true ) {
-            String input = new Scanner(System.in).nextLine();
+			String input = new Scanner(System.in).nextLine();
 			ParsingResult<?> result = new ReportingParseRunner(parser.Target()).run(input);
 			if( result.hasErrors() ) {
 				System.out.println("Parse Errors:\n" + ErrorUtils.printParseErrors(result));