Mercurial Hosting > luan
view src/luan/interp/LuaParser.java @ 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 |
line wrap: on
line source
package luan.interp; import java.util.Scanner; import org.parboiled.BaseParser; import org.parboiled.Parboiled; import org.parboiled.Rule; import org.parboiled.parserunners.ReportingParseRunner; 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> { Rule Target() { return Sequence(ConstExpr(), EOI); } Rule ConstExpr() { return Sequence( Const(), push(new ConstExpr(pop())) ); } Rule Const() { return FirstOf( NilConst(), BooleanConst(), NumberConst(), StringConst() ); } Rule NilConst() { return Sequence( String("nil"), push(null) ); } Rule BooleanConst() { return FirstOf( Sequence( String("true"), push(true) ), Sequence( String("false"), push(false) ) ); } Rule NumberConst() { return Sequence( Number(), push(new LuaNumber((Double)pop())) ); } Rule Number() { return FirstOf( Sequence( IgnoreCase("0x"), OneOrMore(HexDigit()), push((double)Long.parseLong(match(),16)) ), Sequence( DecNumber(), push(Double.parseDouble(match())) ) ); } Rule DecNumber() { return FirstOf( Sequence( Int(), Optional( Ch('.'), Optional(Int()) ), NumberExp() ), Sequence( Ch('.'), Int(), NumberExp() ) ); } Rule NumberExp() { return Optional( IgnoreCase('e'), Optional(AnyOf("+-")), Int() ); } 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 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(); ParsingResult<?> result = new ReportingParseRunner(parser.Target()).run(input); if( result.hasErrors() ) { System.out.println("Parse Errors:\n" + ErrorUtils.printParseErrors(result)); } else { Expr expr = (Expr)result.resultValue; LuaState lua = new LuaState(); Object val = expr.eval(lua); System.out.println("Result: "+Lua.toString(val)); } } } }