diff options
author | Miguel de Icaza <miguel@gnome.org> | 2006-01-04 23:50:06 +0300 |
---|---|---|
committer | Miguel de Icaza <miguel@gnome.org> | 2006-01-04 23:50:06 +0300 |
commit | 2e504eefa0b4550853622c193b5c949cf865c658 (patch) | |
tree | 91483dd237f66532fdbd87d7e90d64d4e710f2d0 /mcs/gmcs | |
parent | 2c0a01246b796cbff75143aceb46ea85f7128890 (diff) |
Revert patch 55055 as it fails to build the following code:
for (LinkedList<int> a = null; ;)
The problem is that simple-name-deambiguation is turned on at this point
because the flag in_namespace_or_typename is false.
svn path=/trunk/mcs/; revision=55075
Diffstat (limited to 'mcs/gmcs')
-rw-r--r-- | mcs/gmcs/ChangeLog | 56 | ||||
-rw-r--r-- | mcs/gmcs/cs-parser.jay | 96 | ||||
-rw-r--r-- | mcs/gmcs/cs-tokenizer.cs | 186 |
3 files changed, 49 insertions, 289 deletions
diff --git a/mcs/gmcs/ChangeLog b/mcs/gmcs/ChangeLog index c806148f9e2..97faccc8dba 100644 --- a/mcs/gmcs/ChangeLog +++ b/mcs/gmcs/ChangeLog @@ -4,62 +4,6 @@ doing a low-level comparission of parameter types. It was lacking a check for __argslist. -2006-01-04 Miguel de Icaza <miguel@novell.com> - - * cs-parser.jay (in_namespace_or_typename): This variable is used - to pass information down to member-name that we are parsing - namespace_or_type_name and that it should not activate the - grammar deambiguation. - - (namespace_or_type_name): Inline the member_name production here - so we can avoid a shift/reduce conflict as we need to turn off - simple-name-deamiguation after the identifier is seen. - - (primary_expression): Replace member_name and IDENTIFIER - DOUBLE_COLON IDENTIFIER rules with a merged rule. This is - required to control the lexer simple-name-deambuguation feature - which needs to be activated after the first IDENTIFIER has been - parsed. - - The new merged rule is member_name_or_qualified_alias. - - (member_name_or_qualified_alias): This rules is a combination of - member_name and IDENTIFIER DOUBLE_COLON IDENTIFIER. After the - first IDENTIFIER is parsed we enable the simple-name-deambuguation - flag in the lexer if we are not in a namespace or typename. - - * cs-tokenizer.cs: Add support for simple-name-deambuguation which - is specified in section 9.2.3 of the third edition of the C# - specification. - - simple-name-deambuguation is a short-hand for the actual required - cases: simple-name, member-access and pointer-member-access. - During those context we must check the token to deambiguate the - expression. - - (next_token_is_allowed_after_generic_closing): This routine - implements the check for the next-token. - - This routine currently contains a hack: it considers "[" a valid - character after the >. This is against the spec, but we require - it for this particular cast: - - (Blah<a,b>[]) - - This is probably a sign that something is wrong elsewhere. - - (Position): Introduce a new class to track the current position - instead of saving all the state everywhere. The state was being - incorrecly saved/restored in the past (not complete enough - everywhere). - - Maybe this should become a struct, and saving should not use a - parallel stack, but just use a construct like: - - Position save = current_position; - xxxx - current_position = save; - 2005-12-30 Miguel de Icaza <miguel@novell.com> * expression.cs (ParameterReference.DoResolveBase): Allow diff --git a/mcs/gmcs/cs-parser.jay b/mcs/gmcs/cs-parser.jay index e8c76c34a94..fc62f9fc2c5 100644 --- a/mcs/gmcs/cs-parser.jay +++ b/mcs/gmcs/cs-parser.jay @@ -104,13 +104,6 @@ namespace Mono.CSharp bool global_attrs_enabled = true; bool has_get, has_set; - // - // Used to pass information down to member-name that we are - // parsing namespace_or_type_name and that it should not - // activate the grammar deambiguation. - // - bool in_namespace_or_typename; - %} %token EOF @@ -2702,39 +2695,18 @@ opt_nullable ; namespace_or_type_name - : // - // inline member_name here - // - // IMPORTANT: Keep in sync with member_name (modulo the PushSND handling) - // - IDENTIFIER { - lexer.PushSND (false); - oob_stack.Push (in_namespace_or_typename); - in_namespace_or_typename = true; - } opt_type_argument_list { - lexer.PopSND (); - in_namespace_or_typename = (bool) oob_stack.Pop (); - LocatedToken lt = (LocatedToken) $1; - $$ = new MemberName (lt.Value, (TypeArguments) $3, lt.Location); - } + : member_name | IDENTIFIER DOUBLE_COLON IDENTIFIER { LocatedToken lt1 = (LocatedToken) $1; LocatedToken lt2 = (LocatedToken) $3; $$ = new MemberName (lt1.Value, lt2.Value, lt2.Location); } - | namespace_or_type_name DOT { - lexer.PushSND (false); - } IDENTIFIER opt_type_argument_list { - lexer.PopSND (); - LocatedToken lt = (LocatedToken) $4; - $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $5, lt.Location); + | namespace_or_type_name DOT IDENTIFIER opt_type_argument_list { + LocatedToken lt = (LocatedToken) $3; + $$ = new MemberName ((MemberName) $1, lt.Value, (TypeArguments) $4, lt.Location); } ; - // - // IMPORTANT: - // keep this code in sync (modulo handling of PushSND) with namespace_or_type_name - // member_name : IDENTIFIER opt_type_argument_list { LocatedToken lt = (LocatedToken) $1; @@ -2750,7 +2722,6 @@ opt_type_argument_list if (RootContext.Version == LanguageVersion.ISO_1) Report.FeatureIsNotStandardized (lexer.Location, "generics"); } - | GENERIC_DIMENSION { $$ = new TypeArguments ((int) $1, lexer.Location); @@ -2786,6 +2757,7 @@ type_arguments } ; + /* * Before you think of adding a return_type, notice that we have been * using two rules in the places where it matters (one rule using type @@ -2920,50 +2892,6 @@ array_type } ; -type_argument_list_or_qualified - : opt_type_argument_list - | DOUBLE_COLON IDENTIFIER { $$ = $2; } - ; - -// -// This is used so we can push the SimpleNameDeambiguation state -// before we parse a member-base (which might need the extra token -// reading to deamiguate). -// -// To avoid a grammar conflict between a qualified-alias and a -// member-name, I merged both rules into this one and call -// PushSND before. It does not matter/hurt QualifiedAliasMember -// and helps our cause -// -// This production merges two old productions in primary-expression: -// | member_name -// | IDENTIFIER DOUBLE_COLON IDENTIFIER -// - -member_name_or_qualified_alias - : IDENTIFIER - { - lexer.PushSND (in_namespace_or_typename == false); - } - type_argument_list_or_qualified - { - lexer.PopSND (); - - // - // Its a member-name with or without type-arguments - // - if ($3 == null || $3 is TypeArguments){ - LocatedToken lt = (LocatedToken) $1; - MemberName mn = new MemberName (lt.Value, (TypeArguments) $3, lt.Location); - $$ = mn.GetTypeExpression (); - } else { - LocatedToken lt1 = (LocatedToken) $1; - LocatedToken lt2 = (LocatedToken) $3; - $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, lt2.Location); - } - } - ; - // // Expressions, section 7.5 // @@ -2972,7 +2900,17 @@ primary_expression { // 7.5.1: Literals } - | member_name_or_qualified_alias + | member_name + { + MemberName mn = (MemberName) $1; + $$ = mn.GetTypeExpression (); + } + | IDENTIFIER DOUBLE_COLON IDENTIFIER + { + LocatedToken lt1 = (LocatedToken) $1; + LocatedToken lt2 = (LocatedToken) $3; + $$ = new QualifiedAliasMember (lt1.Value, lt2.Value, lt2.Location); + } | parenthesized_expression | default_value_expression | member_access @@ -4103,7 +4041,7 @@ opt_statement_list ; statement_list - : statement + : statement | statement_list statement ; diff --git a/mcs/gmcs/cs-tokenizer.cs b/mcs/gmcs/cs-tokenizer.cs index 7a61c61970a..da63a863aa7 100644 --- a/mcs/gmcs/cs-tokenizer.cs +++ b/mcs/gmcs/cs-tokenizer.cs @@ -44,7 +44,6 @@ namespace Mono.CSharp bool handle_assembly = false; bool handle_constraints = false; bool handle_typeof = false; - bool simple_name_deambiguation = false; Location current_location; Location current_comment_location = Location.Null; ArrayList escapedIdentifiers = new ArrayList (); @@ -173,25 +172,6 @@ namespace Mono.CSharp } } - Stack state = new Stack (); - - // - // Sets the new state for the simple-name-deambiguation. - // - public void PushSND (bool value) - { - state.Push (simple_name_deambiguation); - simple_name_deambiguation = value; - } - - // - // Restores the previous state for the simple-name-deambiguation. - // - public void PopSND () - { - simple_name_deambiguation = (bool) state.Pop (); - } - public XmlCommentState doc_state { get { return xmlDocState; } set { @@ -275,55 +255,6 @@ namespace Mono.CSharp } } - // - // 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) { @@ -547,12 +478,7 @@ namespace Mono.CSharp return false; } - // - // The level indicates the nestedness level. This is required - // to perform the extra check in case that simple_name_deambiguation - // is set to true - // - bool parse_less_than (int level) + bool parse_less_than () { start: int the_token = token (); @@ -588,25 +514,14 @@ namespace Mono.CSharp again: the_token = token (); - if (the_token == Token.OP_GENERICS_GT){ - // - // Check for the 9.2.3 special cases - // - if (level == 0 && simple_name_deambiguation){ - PushPosition (); - bool v = next_token_is_allowed_after_generic_closing (); - PopPosition (); - return v; - } + 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) goto again; else if (the_token == Token.OP_GENERICS_LT) { - if (!parse_less_than (level+1)) + if (!parse_less_than ()) return false; goto again; } else if (the_token == Token.OPEN_BRACKET) { @@ -622,61 +537,7 @@ namespace Mono.CSharp return false; } - // - // This method is used to deamiguate the meaning of '>' - // while parsing a '<'...'>' structure. It implements the - // check specified in 9.2.3 "Grammar Ambiguities" on the C# 3rd - // edition - // - bool next_token_is_allowed_after_generic_closing () - { - PushPosition (); - int next_token = token (); - bool ret; - - //Console.WriteLine ("NextToken used for deambiguation is: " + next_token); - if (next_token == Token.OPEN_PARENS || - next_token == Token.CLOSE_PARENS || - next_token == Token.CLOSE_PARENS_OPEN_PARENS || - next_token == Token.CLOSE_PARENS_MINUS || - next_token == Token.CLOSE_PARENS_CAST || - next_token == Token.CLOSE_PARENS_NO_CAST || - next_token == Token.CLOSE_PARENS || - next_token == Token.CLOSE_BRACKET || - next_token == Token.COLON || next_token == Token.SEMICOLON || - next_token == Token.COMMA || next_token == Token.DOT || - next_token == Token.INTERR || - next_token == Token.OP_NE || next_token == Token.OP_EQ) - ret = true; - else - ret = false; - - // - // The following line is a *hack*, it is here to parse: - // (Blah<a,b>[]) case. but it is likely going to show - // up as another bug elsewhere. - // - // The following test case fails without this: - // - // namespace System.Collections.Generic { - // public class Dictionary<TKey, TValue> { - // public void ContainsValue (object b){ - // object a = (KeyValuePair<TKey, TValue> []) b; - // } } - // - // This probably means that we should have turned - // deambuguation off in this particular context, but - // am puzzled about how to fix it. - // - if (next_token == Token.OPEN_BRACKET) - ret = true; - - PopPosition (); - - return ret; - } - - public int parsing_generic_less_than = 0; + int parsing_generic_less_than = 0; int is_punct (char c, ref bool doread) { @@ -707,9 +568,16 @@ namespace Mono.CSharp --deambiguate_close_parens; - PushPosition (); + // Save current position and parse next token. + int old = reader.Position; + int old_ref_line = ref_line; + int old_col = col; + int new_token = token (); - PopPosition (); + reader.Position = old; + ref_line = old_ref_line; + col = old_col; + putback_char = -1; if (new_token == Token.OPEN_PARENS) return Token.CLOSE_PARENS_OPEN_PARENS; @@ -737,21 +605,22 @@ namespace Mono.CSharp 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; } - PopPosition (); + reader.Position = old; + putback_char = -1; } // Save current position and parse next token. - PushPosition (); - bool is_generic_lt = parse_less_than (0); - PopPosition (); + old = reader.Position; + bool is_generic_lt = parse_less_than (); + reader.Position = old; + putback_char = -1; if (is_generic_lt) { parsing_generic_less_than++; @@ -1383,7 +1252,8 @@ namespace Mono.CSharp if (putback_char != -1) { x = putback_char; putback_char = -1; - } else + } + else x = reader.Read (); if (x == '\n') { line++; @@ -2145,7 +2015,12 @@ namespace Mono.CSharp if (res == Token.PARTIAL) { // Save current position and parse next token. - PushPosition (); + int old = reader.Position; + int old_putback = putback_char; + int old_ref_line = ref_line; + int old_col = col; + + putback_char = -1; int next_token = token (); bool ok = (next_token == Token.CLASS) || @@ -2153,7 +2028,10 @@ namespace Mono.CSharp (next_token == Token.INTERFACE) || (next_token == Token.ENUM); // "partial" is a keyword in 'partial enum', even though it's not valid - PopPosition (); + reader.Position = old; + ref_line = old_ref_line; + col = old_col; + putback_char = old_putback; if (ok) return res; |