+#if GMCS_SOURCE
+ bool parse_generic_dimension (out int dimension)
+ {
+ dimension = 1;
+
+ 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;
+ }
+
+ bool parse_less_than ()
+ {
+ start:
+ int the_token = token ();
+ if (the_token == Token.OPEN_BRACKET) {
+ do {
+ the_token = token ();
+ } while (the_token != Token.CLOSE_BRACKET);
+ the_token = token ();
+ }
+ switch (the_token) {
+ case Token.IDENTIFIER:
+ case Token.OBJECT:
+ case Token.STRING:
+ case Token.BOOL:
+ case Token.DECIMAL:
+ case Token.FLOAT:
+ case Token.DOUBLE:
+ case Token.SBYTE:
+ case Token.BYTE:
+ case Token.SHORT:
+ case Token.USHORT:
+ case Token.INT:
+ case Token.UINT:
+ case Token.LONG:
+ case Token.ULONG:
+ case Token.CHAR:
+ case Token.VOID:
+ break;
+
+ default:
+ return false;
+ }
+ again:
+ the_token = token ();
+
+ if (the_token == Token.OP_GENERICS_GT)
+ return true;
+ else if ((the_token == Token.COMMA) || (the_token == Token.DOT))
+ goto start;
+ else if (the_token == Token.INTERR || the_token == Token.STAR)
+ goto again;
+ else if (the_token == Token.OP_GENERICS_LT) {
+ if (!parse_less_than ())
+ return false;
+ goto again;
+ } else if (the_token == Token.OPEN_BRACKET) {
+ rank_specifiers:
+ the_token = token ();
+ if (the_token == Token.CLOSE_BRACKET)
+ goto again;
+ else if (the_token == Token.COMMA)
+ goto rank_specifiers;
+ return false;
+ }
+
+ return false;
+ }
+
+ int parsing_generic_less_than = 0;
+
+ public void PutbackNullable ()
+ {
+ if (nullable_pos < 0)
+ throw new Exception ();
+
+ current_token = -1;
+ val = null;
+ reader.Position = nullable_pos;
+
+ putback_char = '?';
+ }
+
+ public void PutbackCloseParens ()
+ {
+ putback_char = ')';
+ }
+
+
+ int nullable_pos = -1;
+
+ public void CheckNullable (bool is_nullable)
+ {
+ if (is_nullable)
+ nullable_pos = reader.Position;
+ else
+ nullable_pos = -1;
+ }
+#endif