comparison src/luan/interp/LuaParser.java @ 14:2ddf85634d20

whitespace handling; comments; if/while/repeat statements; git-svn-id: https://luan-java.googlecode.com/svn/trunk@15 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Mon, 26 Nov 2012 10:18:46 +0000
parents 9cea1aea5eef
children bb59d7ea223b
comparison
equal deleted inserted replaced
13:3b22ffbdb83a 14:2ddf85634d20
9 import org.parboiled.BaseParser; 9 import org.parboiled.BaseParser;
10 import org.parboiled.Parboiled; 10 import org.parboiled.Parboiled;
11 import org.parboiled.Rule; 11 import org.parboiled.Rule;
12 import org.parboiled.parserunners.ReportingParseRunner; 12 import org.parboiled.parserunners.ReportingParseRunner;
13 import org.parboiled.support.ParsingResult; 13 import org.parboiled.support.ParsingResult;
14 import org.parboiled.support.Var;
15 import org.parboiled.support.StringVar;
16 import org.parboiled.support.ValueStack;
14 import org.parboiled.errors.ErrorUtils; 17 import org.parboiled.errors.ErrorUtils;
15 import luan.Lua; 18 import luan.Lua;
16 import luan.LuaNumber; 19 import luan.LuaNumber;
17 import luan.LuaState; 20 import luan.LuaState;
18 21
19 22
20 public class LuaParser extends BaseParser<Object> { 23 public class LuaParser extends BaseParser<Object> {
24 static final Object PAREN = new Object();
21 25
22 public Rule Target() { 26 public Rule Target() {
23 return Sequence( 27 return Sequence(
24 Spaces(), 28 Spaces(),
25 FirstOf( 29 FirstOf(
49 return true; 53 return true;
50 } 54 }
51 55
52 Stmt newChunk() { 56 Stmt newChunk() {
53 @SuppressWarnings("unchecked") 57 @SuppressWarnings("unchecked")
54 List<Stmt> stmts = (List<Stmt>)peek(); 58 List<Stmt> stmts = (List<Stmt>)pop();
55 switch( stmts.size() ) { 59 switch( stmts.size() ) {
56 case 0: 60 case 0:
57 return Stmt.EMPTY; 61 return Stmt.EMPTY;
58 case 1: 62 case 1:
59 return stmts.get(0); 63 return stmts.get(0);
61 return new Block(stmts.toArray(new Stmt[0])); 65 return new Block(stmts.toArray(new Stmt[0]));
62 } 66 }
63 } 67 }
64 68
65 Rule StmtSep() { 69 Rule StmtSep() {
66 return Sequence( OneOrMore(AnyOf(";\r\n")), Spaces() ); 70 return Sequence(
71 FirstOf(
72 ';',
73 Sequence(
74 Optional( "--", ZeroOrMore(NoneOf("\r\n")) ),
75 EndOfLine()
76 )
77 ),
78 Spaces()
79 );
80 }
81
82 Rule EndOfLine() {
83 return FirstOf("\r\n", '\r', '\n');
67 } 84 }
68 85
69 Rule Stmt() { 86 Rule Stmt() {
70 return Sequence( 87 return Sequence(
71 FirstOf( 88 FirstOf(
89 WhileStmt(),
90 RepeatStmt(),
91 IfStmt(),
72 SetStmt(), 92 SetStmt(),
73 ExpressionsStmt() 93 ExpressionsStmt()
74 ), 94 ),
75 addStmt() 95 addStmt()
76 ); 96 );
77 } 97 }
78 98
79 Rule ExpressionsStmt() { 99 Rule WhileStmt() {
80 return Sequence( 100 return Sequence(
81 ExpList(), 101 "while", Spaces(), Expr(), "do", Spaces(), Chunk(), "end", Spaces(),
82 push( new ExpressionsStmt((Expressions)pop()) ) 102 push( new WhileStmt( expr(pop(1)), (Stmt)pop() ) )
83 ); 103 );
104 }
105
106 Rule RepeatStmt() {
107 return Sequence(
108 "repeat", Spaces(), Chunk(), "until", Spaces(), Expr(),
109 push( new RepeatStmt( (Stmt)pop(1), expr(pop()) ) )
110 );
111 }
112
113 Rule IfStmt() {
114 Var<Integer> n = new Var<Integer>(1);
115 return Sequence(
116 "if", Spaces(), Expr(), "then", Spaces(), Chunk(),
117 push(Stmt.EMPTY),
118 ZeroOrMore(
119 "elseif", Spaces(), drop(), Expr(), "then", Spaces(), Chunk(),
120 push(Stmt.EMPTY),
121 n.set(n.get()+1)
122 ),
123 Optional(
124 "else", Spaces(), drop(), Chunk()
125 ),
126 "end", Spaces(),
127 buildIfStmt(n.get())
128 );
129 }
130
131 boolean buildIfStmt(int n) {
132 while( n-- > 0 ) {
133 Stmt elseStmt = (Stmt)pop();
134 Stmt thenStmt = (Stmt)pop();
135 Expr cnd = expr(pop());
136 push( new IfStmt(cnd,thenStmt,elseStmt) );
137 }
138 return true;
84 } 139 }
85 140
86 Rule SetStmt() { 141 Rule SetStmt() {
87 return Sequence( 142 return Sequence(
88 VarList(), 143 VarList(),
89 '=', Spaces(), 144 '=', Spaces(),
90 ExpList(), 145 ExpList(),
91 push( newSetStmt() ) 146 push( newSetStmt() )
147 );
148 }
149
150 Rule ExpressionsStmt() {
151 return Sequence(
152 ExpList(),
153 push( new ExpressionsStmt((Expressions)pop()) )
92 ); 154 );
93 } 155 }
94 156
95 SetStmt newSetStmt() { 157 SetStmt newSetStmt() {
96 Expressions values = (Expressions)pop(); 158 Expressions values = (Expressions)pop();
168 return Sequence( 230 return Sequence(
169 TermExpr(), 231 TermExpr(),
170 ZeroOrMore( 232 ZeroOrMore(
171 FirstOf( 233 FirstOf(
172 Sequence( '+', Spaces(), TermExpr(), push( new AddExpr(expr(pop(1)),expr(pop())) ) ), 234 Sequence( '+', Spaces(), TermExpr(), push( new AddExpr(expr(pop(1)),expr(pop())) ) ),
173 Sequence( '-', Spaces(), TermExpr(), push( new SubExpr(expr(pop(1)),expr(pop())) ) ) 235 Sequence( '-', TestNot('-'), Spaces(), TermExpr(), push( new SubExpr(expr(pop(1)),expr(pop())) ) )
174 ) 236 )
175 ) 237 )
176 ); 238 );
177 } 239 }
178 240
190 } 252 }
191 253
192 Rule UnaryExpr() { 254 Rule UnaryExpr() {
193 return FirstOf( 255 return FirstOf(
194 Sequence( '#', Spaces(), PowExpr(), push( new LenExpr(expr(pop())) ) ), 256 Sequence( '#', Spaces(), PowExpr(), push( new LenExpr(expr(pop())) ) ),
195 Sequence( '-', Spaces(), PowExpr(), push( new UnmExpr(expr(pop())) ) ), 257 Sequence( '-', TestNot('-'), Spaces(), PowExpr(), push( new UnmExpr(expr(pop())) ) ),
196 Sequence( "not", Spaces(), PowExpr(), push( new NotExpr(expr(pop())) ) ), 258 Sequence( "not", Spaces(), PowExpr(), push( new NotExpr(expr(pop())) ) ),
197 PowExpr() 259 PowExpr()
198 ); 260 );
199 } 261 }
200 262
214 } 276 }
215 277
216 Rule TableExpr() { 278 Rule TableExpr() {
217 return Sequence( 279 return Sequence(
218 '{', Spaces(), 280 '{', Spaces(),
281 push(PAREN),
219 push( new ArrayList<TableExpr.Field>() ), 282 push( new ArrayList<TableExpr.Field>() ),
220 push( 1.0 ), // counter 283 push( 1.0 ), // counter
221 Optional( 284 Optional(
222 Field(), 285 Field(),
223 ZeroOrMore( 286 ZeroOrMore(
224 FieldSep(), 287 FieldSep(),
225 Field() 288 Field()
226 ), 289 ),
227 Optional( FieldSep() ) 290 Optional( FieldSep() )
228 ), 291 ),
229 '}', Spaces(), 292 '}',
230 push( newTableExpr() ) 293 push( newTableExpr() ),
294 drop(1),
295 Spaces()
231 ); 296 );
232 } 297 }
233 298
234 TableExpr newTableExpr() { 299 TableExpr newTableExpr() {
235 pop(); // counter 300 pop(); // counter
290 355
291 Rule Var() { 356 Rule Var() {
292 return Sequence( 357 return Sequence(
293 FirstOf( 358 FirstOf(
294 Sequence( 359 Sequence(
295 '(', Spaces(), Expr(), ')', Spaces(), 360 '(', Spaces(), push(PAREN), Expr(), ')', drop(1), Spaces(),
296 push(expr(pop())), 361 push(expr(pop())),
297 push(null) // marker 362 push(null) // marker
298 ), 363 ),
299 Sequence( 364 Sequence(
300 push(EnvExpr.INSTANCE), 365 push(EnvExpr.INSTANCE),
325 // function should be on top of the stack 390 // function should be on top of the stack
326 Rule Args() { 391 Rule Args() {
327 return Sequence( 392 return Sequence(
328 FirstOf( 393 FirstOf(
329 Sequence( 394 Sequence(
330 '(', Spaces(), Expressions(), ')', Spaces() 395 '(', Spaces(), push(PAREN), Expressions(), ')', drop(1), Spaces()
331 ), 396 ),
332 Sequence( 397 Sequence(
333 TableExpr(), 398 TableExpr(),
334 push( new ExpList.SingleExpList(expr(pop())) ) 399 push( new ExpList.SingleExpList(expr(pop())) )
335 ), 400 ),
372 } 437 }
373 return true; 438 return true;
374 } 439 }
375 440
376 Rule SubExpr() { 441 Rule SubExpr() {
377 return Sequence( '[', Spaces(), Expr(), ']', Spaces() ); 442 return Sequence( '[', Spaces(), push(PAREN), Expr(), ']', drop(1), Spaces() );
378 } 443 }
379 444
380 Rule Name() { 445 Rule Name() {
381 return Sequence( 446 return Sequence(
382 Sequence( 447 Sequence(
577 sb.append(ch); 642 sb.append(ch);
578 return true; 643 return true;
579 } 644 }
580 645
581 Rule Spaces() { 646 Rule Spaces() {
582 return ZeroOrMore(AnyOf(" \t")); 647 return ZeroOrMore(
648 FirstOf(
649 AnyOf(" \t"),
650 Comment(),
651 Sequence( '\\', EndOfLine() ),
652 Sequence( AnyOf("\r\n"), inParen() )
653 )
654 );
655 }
656
657 boolean inParen() {
658 ValueStack stack = getContext().getValueStack();
659 int size = stack.size();
660 for( int i=0; i<size; i++ ) {
661 if( peek(i) == PAREN )
662 return true;
663 }
664 return false;
665 }
666
667 Rule Comment() {
668 Var<Integer> n = new Var<Integer>();
669 return Sequence(
670 "--[",
671 ZeroOrMore('='),
672 setN(n),
673 '[',
674 ZeroOrMore(
675 TestNot(CommentEnd(n)),
676 ANY
677 ),
678 CommentEnd(n)
679 );
680 }
681
682 Rule CommentEnd(Var<Integer> n) {
683 return Sequence( ']', ZeroOrMore('='), eqN(n), ']' );
684 }
685
686 boolean setN(Var<Integer> n) {
687 return n.set(matchLength());
688 }
689
690 boolean eqN(Var<Integer> n) {
691 return n.get()==matchLength();
583 } 692 }
584 693
585 // for debugging 694 // for debugging
586 boolean print(String s) { 695 boolean print(Object o) {
587 System.out.println(s); 696 System.out.println(o);
588 return true; 697 return true;
589 } 698 }
590 699
591 // for testing 700 // for testing
592 public static void main(String[] args) throws Exception { 701 public static void main(String[] args) throws Exception {