+ case '\\':
+ tokens_seen = true;
+ return consume_identifier (c);
+
+ case '{':
+ val = LocatedToken.Create (ref_line, col);
+ return Token.OPEN_BRACE;
+ case '}':
+ val = LocatedToken.Create (ref_line, col);
+ return Token.CLOSE_BRACE;
+ case '[':
+ // To block doccomment inside attribute declaration.
+ if (doc_state == XmlCommentState.Allowed)
+ doc_state = XmlCommentState.NotAllowed;
+ val = LocatedToken.CreateOptional (ref_line, col);
+ return Token.OPEN_BRACKET;
+ case ']':
+ val = LocatedToken.CreateOptional (ref_line, col);
+ return Token.CLOSE_BRACKET;
+ case '(':
+ val = LocatedToken.Create (ref_line, col);
+ //
+ // An expression versions of parens can appear in block context only
+ //
+ if (parsing_block != 0 && !lambda_arguments_parsing) {
+
+ //
+ // Optmize most common case where we know that parens
+ // is not special
+ //
+ switch (current_token) {
+ case Token.IDENTIFIER:
+ case Token.IF:
+ case Token.FOR:
+ case Token.FOREACH:
+ case Token.TYPEOF:
+ case Token.WHILE:
+ case Token.USING:
+ case Token.DEFAULT:
+ case Token.DELEGATE:
+ case Token.OP_GENERICS_GT:
+ return Token.OPEN_PARENS;
+ }
+
+ // Optimize using peek
+ int xx = peek_char ();
+ switch (xx) {
+ case '(':
+ case '\'':
+ case '"':
+ case '0':
+ case '1':
+ return Token.OPEN_PARENS;
+ }
+
+ lambda_arguments_parsing = true;
+ PushPosition ();
+ d = TokenizeOpenParens ();
+ PopPosition ();
+ lambda_arguments_parsing = false;
+ return d;
+ }
+
+ return Token.OPEN_PARENS;
+ case ')':
+ val = LocatedToken.CreateOptional (ref_line, col);
+ return Token.CLOSE_PARENS;
+ case ',':
+ val = LocatedToken.CreateOptional (ref_line, col);
+ return Token.COMMA;
+ case ';':
+ val = LocatedToken.CreateOptional (ref_line, col);
+ return Token.SEMICOLON;
+ case '~':
+ val = LocatedToken.Create (ref_line, col);
+ return Token.TILDE;
+ case '?':
+ val = LocatedToken.Create (ref_line, col);
+ return TokenizePossibleNullableType ();
+ case '<':
+ val = LocatedToken.Create (ref_line, col);
+ if (parsing_generic_less_than++ > 0)
+ return Token.OP_GENERICS_LT;
+
+ return TokenizeLessThan ();
+
+ case '>':
+ val = LocatedToken.Create (ref_line, col);
+ d = peek_char ();
+
+ if (d == '='){
+ get_char ();
+ return Token.OP_GE;
+ }
+
+ if (parsing_generic_less_than > 1 || (parsing_generic_less_than == 1 && d != '>')) {
+ parsing_generic_less_than--;
+ return Token.OP_GENERICS_GT;
+ }
+
+ if (d == '>') {
+ get_char ();
+ d = peek_char ();
+
+ if (d == '=') {
+ get_char ();
+ return Token.OP_SHIFT_RIGHT_ASSIGN;
+ }
+ return Token.OP_SHIFT_RIGHT;
+ }
+
+ return Token.OP_GT;
+
+ case '+':
+ val = LocatedToken.Create (ref_line, col);
+ d = peek_char ();
+ if (d == '+') {
+ d = Token.OP_INC;
+ } else if (d == '=') {
+ d = Token.OP_ADD_ASSIGN;
+ } else {
+ return Token.PLUS;
+ }
+ get_char ();
+ return d;
+
+ case '-':
+ val = LocatedToken.Create (ref_line, col);
+ d = peek_char ();
+ if (d == '-') {
+ d = Token.OP_DEC;
+ } else if (d == '=')
+ d = Token.OP_SUB_ASSIGN;
+ else if (d == '>')
+ d = Token.OP_PTR;
+ else {
+ return Token.MINUS;
+ }
+ get_char ();
+ return d;
+
+ case '!':
+ val = LocatedToken.Create (ref_line, col);
+ if (peek_char () == '='){
+ get_char ();
+ return Token.OP_NE;
+ }
+ return Token.BANG;
+
+ case '=':
+ val = LocatedToken.Create (ref_line, col);
+ d = peek_char ();
+ if (d == '='){
+ get_char ();
+ return Token.OP_EQ;
+ }
+ if (d == '>'){
+ get_char ();
+ return Token.ARROW;
+ }
+
+ return Token.ASSIGN;
+
+ case '&':
+ val = LocatedToken.Create (ref_line, col);
+ d = peek_char ();
+ if (d == '&'){
+ get_char ();
+ return Token.OP_AND;
+ }
+ if (d == '='){
+ get_char ();
+ return Token.OP_AND_ASSIGN;
+ }
+ return Token.BITWISE_AND;
+
+ case '|':
+ val = LocatedToken.Create (ref_line, col);
+ d = peek_char ();
+ if (d == '|'){
+ get_char ();
+ return Token.OP_OR;
+ }
+ if (d == '='){
+ get_char ();
+ return Token.OP_OR_ASSIGN;
+ }
+ return Token.BITWISE_OR;
+
+ case '*':
+ val = LocatedToken.Create (ref_line, col);
+ if (peek_char () == '='){
+ get_char ();
+ return Token.OP_MULT_ASSIGN;
+ }
+ return Token.STAR;
+
+ case '/':
+ d = peek_char ();
+ if (d == '='){
+ val = LocatedToken.Create (ref_line, col);
+ get_char ();
+ return Token.OP_DIV_ASSIGN;
+ }
+
+ // Handle double-slash comments.