public static Int32 Parse(List<Token> src, Int32 begin, out Expr expr) { //expr = null; Int32 current; Int32 saved; if (Parser.IsKeyword(src[begin], KeywordVal.SIZEOF)) { // 1. sizeof current = begin + 1; // 1.1. try to match type_name saved = current; TypeName type_name; current = ParseTypeName(src, current, out type_name); if (current != -1) { // 1.1. -- successful match expr = new SizeofType(type_name); return current; } // 1.2. type_name match failed, try unary_expression current = saved; current = _unary_expression.Parse(src, current, out expr); if (current == -1) { expr = null; return -1; } // 1.2. -- successful match expr = new SizeofExpr(expr); return current; } // sizeof // 2. postfix_expression current = _postfix_expression.Parse(src, begin, out expr); if (current != -1) { // successful match return current; } // now only operators are left if (src[begin].type != TokenType.OPERATOR) { return -1; } current = begin; OperatorVal val = ((TokenOperator)src[begin]).val; switch (val) { case OperatorVal.INC: // '++' current++; current = _unary_expression.Parse(src, current, out expr); if (current == -1) { expr = null; return -1; } expr = new PreIncrement(expr); return current; case OperatorVal.DEC: // '--' current++; current = _unary_expression.Parse(src, current, out expr); if (current == -1) { expr = null; return -1; } expr = new PreDecrement(expr); return current; case OperatorVal.BITAND: // '&' (reference) current++; current = _cast_expression.Parse(src, current, out expr); if (current == -1) { expr = null; return -1; } expr = new Reference(expr); return current; case OperatorVal.MULT: // '*' (dereference) current++; current = _cast_expression.Parse(src, current, out expr); if (current == -1) { expr = null; return -1; } expr = new Dereference(expr); return current; case OperatorVal.ADD: // '+' (positive) current++; current = _cast_expression.Parse(src, current, out expr); if (current == -1) { expr = null; return -1; } expr = new Positive(expr); return current; case OperatorVal.SUB: // '-' (negative) current++; current = _cast_expression.Parse(src, current, out expr); if (current == -1) { expr = null; return -1; } expr = new Negative(expr); return current; case OperatorVal.TILDE: // '~' (bitwise not) current++; current = _cast_expression.Parse(src, current, out expr); if (current == -1) { expr = null; return -1; } expr = new BitwiseNot(expr); return current; case OperatorVal.NOT: // '!' (logical not) current++; current = _cast_expression.Parse(src, current, out expr); if (current == -1) { expr = null; return -1; } expr = new LogicalNot(expr); return current; default: // no match return -1; } // case (val) }
public static Int32 Parse(List<Token> src, Int32 begin, out Expr expr) { // step 1. match primary_expression Int32 current = _primary_expression.Parse(src, begin, out expr); if (current == -1) { expr = null; return -1; } // step 2. match postfixes while (true) { if (src[current].type != TokenType.OPERATOR) { return current; } OperatorVal val = ((TokenOperator)src[current]).val; switch (val) { case OperatorVal.LBRACKET: // '[' current++; // 1. match expression Expr idx; current = _expression.Parse(src, current, out idx); if (current == -1) { expr = null; return -1; } // 2. match ']' if (!Parser.IsOperator(src[current], OperatorVal.RBRACKET)) { expr = null; return -1; } current++; // successful match expr = new Dereference(new Add(expr, idx)); // expr = new ArrayElement(expr, idx); break; case OperatorVal.LPAREN: // '(' current++; // 1. match arglist, if no match, assume empty arglist List<Expr> args; Int32 saved = current; current = _argument_expression_list.Parse(src, current, out args); if (current == -1) { args = new List<Expr>(); current = saved; } // 2. match ')' if (!Parser.IsOperator(src[current], OperatorVal.RPAREN)) { expr = null; return -1; } current++; // successful match expr = new FuncCall(expr, args); break; case OperatorVal.PERIOD: // '.' current++; // match identifier if (src[current].type != TokenType.IDENTIFIER) { expr = null; return -1; } String attrib = ((TokenIdentifier)src[current]).val; current++; // successful match expr = new SyntaxTree.Attribute(expr, new Variable(attrib)); break; case OperatorVal.RARROW: // '->' current++; if (src[current].type != TokenType.IDENTIFIER) { return -1; } String pattrib = ((TokenIdentifier)src[current]).val; current++; // successful match expr = new SyntaxTree.Attribute(new Dereference(expr), new Variable(pattrib)); // expr = new PointerAttribute(expr, new Variable(pattrib)); break; case OperatorVal.INC: // '++' current++; // successful match expr = new PostIncrement(expr); break; case OperatorVal.DEC: // '--' current++; // successful match expr = new PostDecrement(expr); break; default: // no more postfix return current; } // case (val) } // while (true) }