- again:
- int the_token = token ();
- if (the_token == Token.OP_GENERICS_GT)
- return true;
- else if (the_token == Token.COMMA) {
- dimension++;
- goto again;
- }
-
- return false;
- }
-#endif
-
- public int peek_token ()
- {
- int the_token;
-
- PushPosition ();
- the_token = token ();
- PopPosition ();
-
- return the_token;
- }
-
- bool parse_namespace_or_typename (int next)
- {
- if (next == -1)
- next = peek_token ();
- while (next == Token.IDENTIFIER){
- token ();
- again:
- next = peek_token ();
- if (next == Token.DOT || next == Token.DOUBLE_COLON){
- token ();
- next = peek_token ();
- continue;
- }
- if (next == Token.OP_GENERICS_LT){
- token ();
- if (!parse_less_than ())
- return false;
- goto again;
- }
- return true;
- }
-
- return false;
- }
-
- bool is_simple_type (int token)
- {
- return (token == Token.BOOL ||
- token == Token.DECIMAL ||
- token == Token.SBYTE ||
- token == Token.BYTE ||
- token == Token.SHORT ||
- token == Token.USHORT ||
- token == Token.INT ||
- token == Token.UINT ||
- token == Token.LONG ||
- token == Token.ULONG ||
- token == Token.CHAR ||
- token == Token.FLOAT ||
- token == Token.DOUBLE);
- }
-
- bool is_builtin_reference_type (int token)
- {
- return (token == Token.OBJECT || token == Token.STRING);
- }
-
- bool parse_opt_rank (int next)
- {
- while (true){
- if (next != Token.OPEN_BRACKET)
- return true;
-
- token ();
- while (true){
- next = token ();
- if (next == Token.CLOSE_BRACKET){
- next = peek_token ();
- break;
- }
- if (next == Token.COMMA)
- continue;
-
- return false;
- }
- }
- }
-
- bool parse_type ()
- {
- int next = peek_token ();
-
- if (is_simple_type (next)){
- token ();
- next = peek_token ();
- if (next == Token.INTERR)
- token ();
- return parse_opt_rank (peek_token ());
- }
- if (parse_namespace_or_typename (next)){
- next = peek_token ();
- if (next == Token.INTERR)
- token ();
- return parse_opt_rank (peek_token ());
- } else if (is_builtin_reference_type (next)){
- token ();
- return parse_opt_rank (peek_token ());
- }
-
- return false;
- }
-
- //
- // Invoked after '(' has been seen and tries to parse:
- // type identifier [, type identifier]*
- //
- // if this is the case, instead of returning an
- // OPEN_PARENS token we return a special token that
- // triggers lambda parsing.
- //
- // This is needed because we can not introduce the
- // explicitly_typed_lambda_parameter_list after a '(' in the
- // grammar without introducing reduce/reduce conflicts.
- //
- // We need to parse a type and if it is followed by an
- // identifier, we know it has to be parsed as a lambda
- // expression.
- //
- // the type expression can be prefixed with `ref' or `out'
- //
- public bool parse_lambda_parameters ()
- {
- while (true){
- int next = peek_token ();
-
- if (next == Token.REF || next == Token.OUT)
- token ();
-
- if (parse_type ()){
- next = peek_token ();
- if (next == Token.IDENTIFIER){
- token ();
- next = peek_token ();
- if (next == Token.COMMA){
- token ();
- continue;
- }
- if (next == Token.CLOSE_PARENS)
- return true;
- }
- }
- return false;
- }
- }
-
- int parsing_generic_less_than = 0;
-
- int is_punct (char c, ref bool doread)
- {
- int d;
- int t;
-
- doread = false;
-
- switch (c){
- case '{':
- val = Location;
- return Token.OPEN_BRACE;
- case '}':
- val = Location;
- return Token.CLOSE_BRACE;
- case '[':
- // To block doccomment inside attribute declaration.
- if (doc_state == XmlCommentState.Allowed)
- doc_state = XmlCommentState.NotAllowed;
- return Token.OPEN_BRACKET;
- case ']':
- return Token.CLOSE_BRACKET;
- case '(':
- if (IsLinqEnabled){
- PushPosition ();
- bool have_lambda_parameter = parse_lambda_parameters ();
- PopPosition ();
-
- if (have_lambda_parameter)
- return Token.OPEN_PARENS_LAMBDA;
- else
- return Token.OPEN_PARENS;
- } else
- return Token.OPEN_PARENS;
- case ')': {
- if (deambiguate_close_parens == 0)
- return Token.CLOSE_PARENS;
-
- --deambiguate_close_parens;
-
- PushPosition ();
-
- int new_token = xtoken ();
-
- PopPosition ();
-
- if (new_token == Token.OPEN_PARENS)
- return Token.CLOSE_PARENS_OPEN_PARENS;
- else if (new_token == Token.MINUS)
- return Token.CLOSE_PARENS_MINUS;
- else if (IsCastToken (new_token))
- return Token.CLOSE_PARENS_CAST;
- else
- return Token.CLOSE_PARENS_NO_CAST;
- }
-
- case ',':
- return Token.COMMA;
- case ';':
- val = Location;
- return Token.SEMICOLON;
- case '~':
- val = Location;
- return Token.TILDE;
- case '?':
-#if GMCS_SOURCE
- d = peek_char ();
- if (d == '?') {
- get_char ();
- return Token.OP_COALESCING;
- }
-#endif
- return Token.INTERR;
- }
-#if GMCS_SOURCE
- if (c == '<') {
- if (parsing_generic_less_than++ > 0)
- return Token.OP_GENERICS_LT;
-
- if (handle_typeof) {
- int dimension;
- PushPosition ();
- if (parse_generic_dimension (out dimension)) {
- val = dimension;
- DiscardPosition ();
- return Token.GENERIC_DIMENSION;
- }
- PopPosition ();
- }
-
- // Save current position and parse next token.
- PushPosition ();
- bool is_generic_lt = parse_less_than ();
- PopPosition ();
-
- if (is_generic_lt) {
- return Token.OP_GENERICS_LT;
- } else
- parsing_generic_less_than = 0;
-
- d = peek_char ();
- if (d == '<'){
- get_char ();
- d = peek_char ();
-
- if (d == '='){
- doread = true;
- return Token.OP_SHIFT_LEFT_ASSIGN;
- }
- return Token.OP_SHIFT_LEFT;
- } else if (d == '='){
- doread = true;
- return Token.OP_LE;
- }
- return Token.OP_LT;
- } else if (c == '>') {
- if (parsing_generic_less_than > 0) {
- parsing_generic_less_than--;
- return Token.OP_GENERICS_GT;
- }
-
- d = peek_char ();
- if (d == '>'){
- get_char ();
- d = peek_char ();
-
- if (d == '='){
- doread = true;
- return Token.OP_SHIFT_RIGHT_ASSIGN;
- }
- return Token.OP_SHIFT_RIGHT;
- } else if (d == '='){
- doread = true;
- return Token.OP_GE;
- }
- return Token.OP_GT;
- }
-#endif
- d = peek_char ();
- if (c == '+'){
-
- if (d == '+') {
- val = Location;
- t = Token.OP_INC;
- }
- else if (d == '=')
- t = Token.OP_ADD_ASSIGN;
- else {
- val = Location;
- return Token.PLUS;
- }
- doread = true;
- return t;
- }
- if (c == '-'){
- if (d == '-') {
- val = Location;
- t = Token.OP_DEC;
- }
- else if (d == '=')
- t = Token.OP_SUB_ASSIGN;
- else if (d == '>')
- t = Token.OP_PTR;
- else {
- val = Location;
- return Token.MINUS;
- }
- doread = true;
- return t;
- }
-
- if (c == '!'){
- if (d == '='){
- doread = true;
- return Token.OP_NE;
- }
- val = Location;
- return Token.BANG;
- }
-
- if (c == '='){
- if (d == '='){
- doread = true;
- return Token.OP_EQ;
- }
- if (d == '>'){
- doread = true;
- val = Location;
- return Token.ARROW;
- }
- return Token.ASSIGN;
- }
-
- if (c == '&'){
- if (d == '&'){
- doread = true;
- return Token.OP_AND;
- } else if (d == '='){
- doread = true;
- return Token.OP_AND_ASSIGN;
- }
- val = Location;
- return Token.BITWISE_AND;
- }
-
- if (c == '|'){
- if (d == '|'){
- doread = true;
- return Token.OP_OR;
- } else if (d == '='){
- doread = true;
- return Token.OP_OR_ASSIGN;
- }
- return Token.BITWISE_OR;