~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/nrefactory/ICSharpCode.NRefactory.VB/Parser/VBParser.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
ļ»æ// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
 
2
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
 
3
 
 
4
using System;
 
5
using System.Collections.Generic;
 
6
using System.Diagnostics;
 
7
using System.Linq;
 
8
using System.Text;
 
9
 
 
10
using ICSharpCode.NRefactory.VB.Ast;
 
11
using ICSharpCode.NRefactory.VB.Visitors;
 
12
 
 
13
namespace ICSharpCode.NRefactory.VB.Parser
 
14
{
 
15
        internal partial class VBParser : IDisposable
 
16
        {
 
17
                VBLexer lexer;
 
18
                Stack<AstNode> stack;
 
19
                CompilationUnit compilationUnit;
 
20
                int errDist = MinErrDist;
 
21
                
 
22
                const int    MinErrDist   = 2;
 
23
                const string ErrMsgFormat = "-- line {0} col {1}: {2}";  // 0=line, 1=column, 2=text
 
24
                
 
25
                public VBParser(VBLexer lexer)
 
26
                {
 
27
                        this.errors = lexer.Errors;
 
28
                        errors.SynErr = new ErrorCodeProc(SynErr);
 
29
                        this.lexer = (VBLexer)lexer;
 
30
                        this.stack = new Stack<AstNode>();
 
31
                }
 
32
                
 
33
                #region Infrastructure
 
34
                void NodeStart(AstNode node)
 
35
                {
 
36
                        stack.Push(node);
 
37
                }
 
38
                
 
39
                void NodeEnd(AstNode currentNode, Role role)
 
40
                {
 
41
                        AstNode node = stack.Pop();
 
42
                        Debug.Assert(currentNode == node);
 
43
                        stack.Peek().AddChildUntyped(node, role);
 
44
                }
 
45
                
 
46
                void AddTerminal(Role<VBTokenNode> role)
 
47
                {
 
48
                        stack.Peek().AddChild(new VBTokenNode(t.Location, t.EndLocation), role);
 
49
                }
 
50
                
 
51
                void AddChild<T>(T childNode, Role<T> role) where T : AstNode
 
52
                {
 
53
                        if (childNode != null) {
 
54
                                stack.Peek().AddChild(childNode, role);
 
55
                        }
 
56
                }
 
57
                
 
58
                StringBuilder qualidentBuilder = new StringBuilder();
 
59
 
 
60
                Token t
 
61
                {
 
62
                        [System.Diagnostics.DebuggerStepThrough]
 
63
                        get {
 
64
                                return lexer.Token;
 
65
                        }
 
66
                }
 
67
                
 
68
                Token la
 
69
                {
 
70
                        [System.Diagnostics.DebuggerStepThrough]
 
71
                        get {
 
72
                                return lexer.LookAhead;
 
73
                        }
 
74
                }
 
75
 
 
76
                Token Peek(int n)
 
77
                {
 
78
                        lexer.StartPeek();
 
79
                        Token x = la;
 
80
                        while (n > 0) {
 
81
                                x = lexer.Peek();
 
82
                                n--;
 
83
                        }
 
84
                        return x;
 
85
                }
 
86
 
 
87
                public void Error(string s)
 
88
                {
 
89
                        if (errDist >= MinErrDist) {
 
90
                                this.Errors.Error(la.line, la.col, s);
 
91
                        }
 
92
                        errDist = 0;
 
93
                }
 
94
                #endregion
 
95
                
 
96
                #region Parse
 
97
                public void Parse()
 
98
                {
 
99
                        ParseRoot();
 
100
                }
 
101
                
 
102
                public AstType ParseAstType()
 
103
                {
 
104
                        // TODO
 
105
                        return null;
 
106
                }
 
107
                
 
108
//              public Expression ParseExpression()
 
109
//              {
 
110
//                      lexer.SetInitialContext(SnippetType.Expression);
 
111
//                      lexer.NextToken();
 
112
//                      Location startLocation = la.Location;
 
113
//                      Expression expr;
 
114
//                      Expr(out expr);
 
115
//                      while (la.kind == Tokens.EOL) lexer.NextToken();
 
116
//                      if (expr != null) {
 
117
//                              expr.StartLocation = startLocation;
 
118
//                              expr.EndLocation = t.EndLocation;
 
119
//                              expr.AcceptVisitor(new SetParentVisitor(), null);
 
120
//                      }
 
121
//                      Expect(Tokens.EOF);
 
122
//                      return expr;
 
123
//              }
 
124
                
 
125
//              public BlockStatement ParseBlock()
 
126
//              {
 
127
//                      lexer.NextToken();
 
128
//                      compilationUnit = new CompilationUnit();
 
129
//
 
130
//                      Location startLocation = la.Location;
 
131
//                      Statement st;
 
132
//                      Block(out st);
 
133
//                      if (st != null) {
 
134
//                              st.StartLocation = startLocation;
 
135
//                              if (t != null)
 
136
//                                      st.EndLocation = t.EndLocation;
 
137
//                              else
 
138
//                                      st.EndLocation = la.Location;
 
139
//                              st.AcceptVisitor(new SetParentVisitor(), null);
 
140
//                      }
 
141
//                      Expect(Tokens.EOF);
 
142
//                      return st as BlockStatement;
 
143
//              }
 
144
                
 
145
//              public List<AstNode> ParseTypeMembers()
 
146
//              {
 
147
//                      lexer.NextToken();
 
148
//                      TypeDeclaration newType = new TypeDeclaration(Modifiers.None, null);
 
149
//                      BlockStart(newType);
 
150
//                      ClassBody(newType);
 
151
//                      BlockEnd();
 
152
//                      Expect(Tokens.EOF);
 
153
//                      newType.AcceptVisitor(new SetParentVisitor(), null);
 
154
//                      return newType.Children;
 
155
//              }
 
156
                #endregion
 
157
                
 
158
                #region Conflict Resolvers
 
159
                bool IsAliasImportsClause()
 
160
                {
 
161
                        return IsIdentifierToken(la) && Peek(1).Kind == Tokens.Assign;
 
162
                }
 
163
                
 
164
                static bool IsIdentifierToken(Token tk)
 
165
                {
 
166
                        return Tokens.IdentifierTokens[tk.kind] || tk.kind == Tokens.Identifier;
 
167
                }
 
168
                #endregion
 
169
                
 
170
                /* True, if "." is followed by an ident */
 
171
                bool DotAndIdentOrKw () {
 
172
                        int peek = Peek(1).kind;
 
173
                        return la.kind == Tokens.Dot && (peek == Tokens.Identifier || peek >= Tokens.AddHandler);
 
174
                }
 
175
                
 
176
                bool IsIdentifiedExpressionRange()
 
177
                {
 
178
                        // t = Select
 
179
                        // la = Identifier
 
180
                        // Peek(1) = As or Assign
 
181
                        Token token = Peek(1);
 
182
                        return IsIdentifierToken(la) && (token.kind == Tokens.As || token.kind == Tokens.Assign);
 
183
                }
 
184
                
 
185
                bool IsQueryExpression()
 
186
                {
 
187
                        return (la.kind == Tokens.From || la.kind == Tokens.Aggregate) && IsIdentifierToken(Peek(1));
 
188
                }
 
189
                
 
190
                bool IsEndStmtAhead()
 
191
                {
 
192
                        int peek = Peek(1).kind;
 
193
                        return la.kind == Tokens.End && (peek == Tokens.EOL || peek == Tokens.Colon);
 
194
                }
 
195
 
 
196
                bool IsNotClosingParenthesis() {
 
197
                        return la.kind != Tokens.CloseParenthesis;
 
198
                }
 
199
 
 
200
                /*
 
201
                        True, if ident is followed by "=" or by ":" and "="
 
202
                 */
 
203
                bool IsNamedAssign() {
 
204
                        return Peek(1).kind == Tokens.ColonAssign;
 
205
                }
 
206
 
 
207
                bool IsObjectCreation() {
 
208
                        return la.kind == Tokens.As && Peek(1).kind == Tokens.New;
 
209
                }
 
210
                
 
211
                bool IsNewExpression() {
 
212
                        return la.kind == Tokens.New;
 
213
                }
 
214
 
 
215
                /*
 
216
                        True, if "<" is followed by the ident "assembly" or "module"
 
217
                 */
 
218
                bool IsGlobalAttrTarget () {
 
219
                        Token pt = Peek(1);
 
220
                        return la.kind == Tokens.LessThan && ( string.Equals(pt.val, "assembly", StringComparison.InvariantCultureIgnoreCase) || string.Equals(pt.val, "module", StringComparison.InvariantCultureIgnoreCase));
 
221
                }
 
222
 
 
223
                /*
 
224
                        True if the next token is a "(" and is followed by "," or ")"
 
225
                 */
 
226
                bool IsDims()
 
227
                {
 
228
                        int peek = Peek(1).kind;
 
229
                        return la.kind == Tokens.OpenParenthesis
 
230
                                && (peek == Tokens.Comma || peek == Tokens.CloseParenthesis);
 
231
                }
 
232
                
 
233
                /*
 
234
                        True if the next token is an identifier
 
235
                 */
 
236
                bool IsLoopVariableDeclaration()
 
237
                {
 
238
                        if (!IsIdentifierToken(la))
 
239
                                return false;
 
240
                        lexer.StartPeek();
 
241
                        Token x = lexer.Peek();
 
242
                        if (x.kind == Tokens.OpenParenthesis) {
 
243
                                do {
 
244
                                        x = lexer.Peek();
 
245
                                } while (x.kind == Tokens.Comma);
 
246
                                if (x.kind != Tokens.CloseParenthesis)
 
247
                                        return false;
 
248
                                x = lexer.Peek();
 
249
                        }
 
250
                        return x.kind == Tokens.As || x.kind == Tokens.Assign;
 
251
                }
 
252
 
 
253
                bool IsSize()
 
254
                {
 
255
                        return la.kind == Tokens.OpenParenthesis;
 
256
                }
 
257
 
 
258
                /*
 
259
                        True, if the comma is not a trailing one,
 
260
                        like the last one in: a, b, c,
 
261
                 */
 
262
                bool NotFinalComma() {
 
263
                        int peek = Peek(1).kind;
 
264
                        return la.kind == Tokens.Comma &&
 
265
                                peek != Tokens.CloseCurlyBrace;
 
266
                }
 
267
 
 
268
                /*
 
269
                        True, if the next token is "Else" and this one
 
270
                        if followed by "If"
 
271
                 */
 
272
                bool IsElseIf()
 
273
                {
 
274
                        int peek = Peek(1).kind;
 
275
                        return la.kind == Tokens.Else && peek == Tokens.If;
 
276
                }
 
277
 
 
278
                /*
 
279
        True if the next token is goto and this one is
 
280
        followed by minus ("-") (this is allowd in in
 
281
        error clauses)
 
282
                 */
 
283
                bool IsNegativeLabelName()
 
284
                {
 
285
                        int peek = Peek(1).kind;
 
286
                        return la.kind == Tokens.GoTo && peek == Tokens.Minus;
 
287
                }
 
288
 
 
289
                /*
 
290
        True if the next statement is a "Resume next" statement
 
291
                 */
 
292
                bool IsResumeNext()
 
293
                {
 
294
                        int peek = Peek(1).kind;
 
295
                        return la.kind == Tokens.Resume && peek == Tokens.Next;
 
296
                }
 
297
                
 
298
                /// <summary>
 
299
                /// Returns True, if ident/literal integer is followed by ":"
 
300
                /// </summary>
 
301
                bool IsLabel()
 
302
                {
 
303
                        return (la.kind == Tokens.Identifier || la.kind == Tokens.LiteralInteger)
 
304
                                && Peek(1).kind == Tokens.Colon;
 
305
                }
 
306
                
 
307
                /// <summary>
 
308
                /// Returns true if a property declaration is an automatic property.
 
309
                /// </summary>
 
310
                bool IsAutomaticProperty()
 
311
                {
 
312
                        lexer.StartPeek();
 
313
                        Token tn = la;
 
314
                        int braceCount = 0;
 
315
 
 
316
                        // look for attributes
 
317
                        while (tn.kind == Tokens.LessThan) {
 
318
                                while (braceCount > 0 || tn.kind != Tokens.GreaterThan) {
 
319
                                        tn = lexer.Peek();
 
320
                                        if (tn.kind == Tokens.OpenParenthesis)
 
321
                                                braceCount++;
 
322
                                        if (tn.kind == Tokens.CloseParenthesis)
 
323
                                                braceCount--;
 
324
                                }
 
325
                                Debug.Assert(tn.kind == Tokens.GreaterThan);
 
326
                                tn = lexer.Peek();
 
327
                        }
 
328
                        
 
329
                        // look for modifiers
 
330
                        var allowedTokens = new[] {
 
331
                                Tokens.Public, Tokens.Protected,
 
332
                                Tokens.Friend, Tokens.Private
 
333
                        };
 
334
 
 
335
                        while (allowedTokens.Contains(tn.kind))
 
336
                                tn = lexer.Peek();
 
337
                        
 
338
                        if (tn.Kind != Tokens.Get && tn.Kind != Tokens.Set)
 
339
                                return true;
 
340
 
 
341
                        return false;
 
342
                }
 
343
 
 
344
                bool IsNotStatementSeparator()
 
345
                {
 
346
                        return la.kind == Tokens.Colon && Peek(1).kind == Tokens.EOL;
 
347
                }
 
348
 
 
349
                static bool IsMustOverride(AttributedNode node)
 
350
                {
 
351
                        return node.Modifiers.HasFlag(Modifiers.MustOverride);
 
352
                }
 
353
 
 
354
                /* Writes the type name represented through the expression into the string builder. */
 
355
                /* Returns true when the expression was converted successfully, returns false when */
 
356
                /* There was an unknown expression (e.g. TypeReferenceExpression) in it */
 
357
//              bool WriteFullTypeName(StringBuilder b, Expression expr)
 
358
//              {
 
359
//                      MemberReferenceExpression fre = expr as MemberReferenceExpression;
 
360
//                      if (fre != null) {
 
361
//                              bool result = WriteFullTypeName(b, fre.TargetObject);
 
362
//                              if (b.Length > 0) b.Append('.');
 
363
//                              b.Append(fre.MemberName);
 
364
//                              return result;
 
365
//                      } else if (expr is SimpleNameExpression) {
 
366
//                              b.Append(((SimpleNameExpression)expr).Identifier);
 
367
//                              return true;
 
368
//                      } else {
 
369
//                              return false;
 
370
//                      }
 
371
//              }
 
372
                
 
373
                void EnsureIsZero(Expression expr)
 
374
                {
 
375
                        if (!(expr is PrimitiveExpression) || (expr as PrimitiveExpression).StringValue != "0")
 
376
                                Error("lower bound of array must be zero");
 
377
                }
 
378
                
 
379
                public bool ParseMethodBodies { get; set; }
 
380
                
 
381
                public VBLexer Lexer {
 
382
                        get {
 
383
                                return lexer;
 
384
                        }
 
385
                }
 
386
                
 
387
                public Errors Errors {
 
388
                        get {
 
389
                                return errors;
 
390
                        }
 
391
                }
 
392
                
 
393
                public CompilationUnit CompilationUnit {
 
394
                        get {
 
395
                                return compilationUnit;
 
396
                        }
 
397
                }
 
398
                
 
399
                void SynErr(int n)
 
400
                {
 
401
                        if (errDist >= MinErrDist) {
 
402
                                errors.SynErr(lexer.LookAhead.line, lexer.LookAhead.col, n);
 
403
                        }
 
404
                        errDist = 0;
 
405
                }
 
406
                
 
407
                void SemErr(string msg)
 
408
                {
 
409
                        if (errDist >= MinErrDist) {
 
410
                                errors.Error(lexer.Token.line, lexer.Token.col, msg);
 
411
                        }
 
412
                        errDist = 0;
 
413
                }
 
414
                
 
415
                void Expect(int n)
 
416
                {
 
417
                        if (lexer.LookAhead.kind == n) {
 
418
                                lexer.NextToken();
 
419
                        } else {
 
420
                                SynErr(n);
 
421
                        }
 
422
                }
 
423
                
 
424
                #region System.IDisposable interface implementation
 
425
                [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly")]
 
426
                public void Dispose()
 
427
                {
 
428
                        errors = null;
 
429
                        if (lexer != null) {
 
430
                                lexer.Dispose();
 
431
                        }
 
432
                        lexer = null;
 
433
                }
 
434
                #endregion
 
435
        }
 
436
}