}
}
+ //
+ // This is used when the tokenizer needs to save
+ // the current position as it needs to do some parsing
+ // on its own to deamiguate a token in behalf of the
+ // parser.
+ //
+ Stack position_stack = new Stack ();
+ class Position {
+ public int position;
+ public int ref_line;
+ public int col;
+ public int putback_char;
+ public int previous_col;
+ public int parsing_generic_less_than;
+
+ public Position (Tokenizer t)
+ {
+ position = t.reader.Position;
+ ref_line = t.ref_line;
+ col = t.col;
+ putback_char = t.putback_char;
+ previous_col = t.previous_col;
+ parsing_generic_less_than = t.parsing_generic_less_than;
+ }
+ }
+
+ public void PushPosition ()
+ {
+ position_stack.Push (new Position (this));
+ }
+
+ public void PopPosition ()
+ {
+ Position p = (Position) position_stack.Pop ();
+
+ reader.Position = p.position;
+ ref_line = p.ref_line;
+ col = p.col;
+ putback_char = p.putback_char;
+ previous_col = p.previous_col;
+
+ }
+
+ // Do not reset the position, ignore it.
+ public void DiscardPosition ()
+ {
+ position_stack.Pop ();
+ }
+
static void AddKeyword (string kw, int token) {
keywordStrings.Add (kw, kw);
if (keywords [kw.Length] == null) {
// FIXME: This could be `Location.Push' but we have to
// find out why the MS compiler allows this
//
- Mono.CSharp.Location.Push (file, 0);
+ Mono.CSharp.Location.Push (file);
}
static bool is_identifier_start_character (char c)
{
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:
return true;
else if ((the_token == Token.COMMA) || (the_token == Token.DOT))
goto start;
- else if (the_token == Token.INTERR)
+ else if (the_token == Token.INTERR || the_token == Token.STAR)
goto again;
else if (the_token == Token.OP_GENERICS_LT) {
if (!parse_less_than ())
--deambiguate_close_parens;
- // Save current position and parse next token.
- int old = reader.Position;
- int old_ref_line = ref_line;
- int old_col = col;
-
+ PushPosition ();
int new_token = token ();
- reader.Position = old;
- ref_line = old_ref_line;
- col = old_col;
- putback_char = -1;
+ PopPosition ();
if (new_token == Token.OPEN_PARENS)
return Token.CLOSE_PARENS_OPEN_PARENS;
if (parsing_generic_less_than++ > 0)
return Token.OP_GENERICS_LT;
- int old = reader.Position;
if (handle_typeof) {
int dimension;
+ PushPosition ();
if (parse_generic_dimension (out dimension)) {
val = dimension;
+ DiscardPosition ();
return Token.GENERIC_DIMENSION;
}
- reader.Position = old;
- putback_char = -1;
+ PopPosition ();
}
// Save current position and parse next token.
- old = reader.Position;
+ PushPosition ();
bool is_generic_lt = parse_less_than ();
- reader.Position = old;
- putback_char = -1;
+ PopPosition ();
if (is_generic_lt) {
parsing_generic_less_than++;
return seen_digits;
}
- bool is_hex (int e)
+ static bool is_hex (int e)
{
return (e >= '0' && e <= '9') || (e >= 'A' && e <= 'F') || (e >= 'a' && e <= 'f');
}
- int real_type_suffix (int c)
+ static int real_type_suffix (int c)
{
int t;
// if we have not seen anything in between
// report this error
//
- Report.Warning (78, Location, "The 'l' suffix is easily confused with the digit '1' (use 'L' for clarity)");
+ Report.Warning (78, 4, Location, "The 'l' suffix is easily confused with the digit '1' (use 'L' for clarity)");
}
//
// This goto statement causes the MS CLR 2.0 beta 1 csc to report an error, so
break;
case Token.LITERAL_FLOAT:
try {
- val = (float) System.Double.Parse (s, styles, csharp_format_info);
+ val = float.Parse (s, styles, csharp_format_info);
} catch (OverflowException) {
val = 0.0f;
Report.Error (594, Location, error_details, "float");
goto default;
return v;
default:
- Report.Error (1009, Location, "Unrecognized escape sequence `\\{0}'", (char)d);
+ Report.Error (1009, Location, "Unrecognized escape sequence `\\{0}'", ((char)d).ToString ());
return d;
}
getChar ();
if (putback_char != -1) {
x = putback_char;
putback_char = -1;
- }
- else
+ } else
x = reader.Read ();
if (x == '\n') {
line++;
return val;
}
- bool IsCastToken (int token)
+ static bool IsCastToken (int token)
{
switch (token) {
case Token.BANG:
//
bool PreProcessLine (string arg)
{
- if (arg == "")
+ if (arg.Length == 0)
return false;
if (arg == "default"){
ref_line = line;
ref_name = file_name;
- Location.Push (ref_name, line);
+ Location.Push (ref_name);
return true;
} else if (arg == "hidden"){
//
ref_name = Location.LookupFile (name);
file_name.HasLineDirective = true;
ref_name.HasLineDirective = true;
- Location.Push (ref_name, ref_line);
+ Location.Push (ref_name);
} else {
ref_line = System.Int32.Parse (arg);
}
//
void PreProcessDefinition (bool is_define, string arg)
{
- if (arg == "" || arg == "true" || arg == "false"){
+ if (arg.Length == 0 || arg == "true" || arg == "false"){
Report.Error (1001, Location, "Missing identifer to pre-processor directive");
return;
}
Hashtable w_table = Report.warning_ignore_table;
foreach (int code in codes) {
if (w_table != null && w_table.Contains (code))
- Report.Warning (1635, 1, Location, "Cannot restore warning `CS{0:0000}' because it was disabled globally", code);
+ Report.Warning (1635, 1, Location, String.Format ("Cannot restore warning `CS{0:0000}' because it was disabled globally", code));
Report.RegisterWarningRegion (Location).WarningEnable (Location, code);
}
return;
values[index++] = int.Parse (string_code, System.Globalization.CultureInfo.InvariantCulture);
}
catch (FormatException) {
- Report.Warning (1692, Location, "Invalid number");
+ Report.Warning (1692, 1, Location, "Invalid number");
}
}
return values;
goto case "endif";
case "if":
- if (arg == ""){
+ if (arg.Length == 0){
Error_InvalidDirective ();
return true;
}
bool taking = false;
if (ifstack == null)
- ifstack = new Stack ();
+ ifstack = new Stack (2);
if (ifstack.Count == 0){
taking = true;
return true;
case "warning":
- Report.Warning (1030, Location, "#warning: `{0}'", arg);
+ Report.Warning (1030, 1, Location, "#warning: `{0}'", arg);
return true;
}
if (res == Token.PARTIAL) {
// Save current position and parse next token.
- int old = reader.Position;
- int old_putback = putback_char;
- int old_ref_line = ref_line;
- int old_col = col;
-
- putback_char = -1;
+ PushPosition ();
int next_token = token ();
bool ok = (next_token == Token.CLASS) ||
(next_token == Token.INTERFACE) ||
(next_token == Token.ENUM); // "partial" is a keyword in 'partial enum', even though it's not valid
- reader.Position = old;
- ref_line = old_ref_line;
- col = old_col;
- putback_char = old_putback;
+ PopPosition ();
if (ok)
return res;
current_location = new Location (ref_line, Col);
while ((c = getChar ()) != -1) {
+ loop:
if (is_identifier_part_character ((char) c)){
if (pos == max_id_size){
Report.Error (645, Location, "Identifier too long (limit is 512 chars)");
id_builder [pos++] = (char) c;
// putback_char = -1;
+ } else if (c == '\\') {
+ c = escape (c);
+ goto loop;
} else {
// putback_char = c;
putback (c);
for (int i = 1; i < id_builder.Length; i += 3) {
if (id_builder [i] == '_' && (id_builder [i - 1] == '_' || id_builder [i + 1] == '_')) {
Report.Error (1638, Location,
- "`{0}': Any identifier with double underscores cannot be used when ISO language version mode is specified", val);
+ "`{0}': Any identifier with double underscores cannot be used when ISO language version mode is specified", val.ToString ());
break;
}
}
if (c == -1)
return Token.EOF;
- if (is_identifier_start_character ((char)c)){
+ if (c == '\\' || is_identifier_start_character ((char)c)){
tokens_seen = true;
- return consume_identifier (c);
+ return consume_identifier (c);
}
current_location = new Location (ref_line, Col);
if ((state & REGION) != 0)
Report.Error (1038, Location, "#endregion directive expected");
else
- Report.Error (1027, "Expected `#endif' directive");
+ Report.Error (1027, Location, "Expected `#endif' directive");
}
}