SyntaxTree ParseMainExp() { SyntaxTree exp; switch (LookAhead().m_type) { case (int)TokenType.NIL: case (int)TokenType.FALSE: case (int)TokenType.TRUE: case (int)TokenType.NUMBER: case (int)TokenType.STRING: case (int)TokenType.DOTS: exp = new Terminator(NextToken()); break; case (int)TokenType.FUNCTION: exp = ParseFunctionDef(); break; case (int)TokenType.NAME: case (int)'(': exp = ParsePrefixExp(); break; case (int)'{': exp = ParseTableConstructor(); break; // unop exp priority is 90 less then ^ case (int)'-': case (int)'#': case (int)TokenType.NOT: var unexp = new UnaryExpression(LookAhead().m_line); unexp.op = NextToken(); unexp.exp = ParseExp(90); exp = unexp; break; default: throw NewParserException("unexpect token for main exp", _look_ahead); } return(exp); }
SyntaxTree ParsePrefixExp() { NextToken(); Debug.Assert(_current.m_type == (int)TokenType.NAME || _current.m_type == (int)'('); SyntaxTree exp; if (_current.m_type == (int)'(') { exp = ParseExp(); if (NextToken().m_type != (int)')') { throw NewParserException("expect ')'", _current); } } else { exp = new Terminator(_current); } // table index or func call for (;;) { if (LookAhead().m_type == (int)'[' || LookAhead().m_type == (int)'.') { exp = ParseTableAccessor(exp); } else if (LookAhead().m_type == (int)'(' || LookAhead().m_type == (int)'{') { exp = ParseFunctionCall(exp); } else { break; } } return(exp); }