1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
3
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4
// software and associated documentation files (the "Software"), to deal in the Software
5
// without restriction, including without limitation the rights to use, copy, modify, merge,
6
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7
// to whom the Software is furnished to do so, subject to the following conditions:
9
// The above copyright notice and this permission notice shall be included in all copies or
10
// substantial portions of the Software.
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17
// DEALINGS IN THE SOFTWARE.
20
using System.Collections.Generic;
21
using System.Diagnostics;
24
namespace ICSharpCode.NRefactory.PatternMatching
27
/// Base class for all patterns.
29
public abstract class Pattern : INode
32
/// Gets the string that matches any string.
34
public static readonly string AnyString = "$any$";
36
public static bool MatchString(string pattern, string text)
38
return pattern == AnyString || pattern == text;
41
internal struct PossibleMatch
43
public readonly INode NextOther; // next node after the last matched node
44
public readonly int Checkpoint; // checkpoint
46
public PossibleMatch(INode nextOther, int checkpoint)
48
this.NextOther = nextOther;
49
this.Checkpoint = checkpoint;
61
INode INode.NextSibling {
65
INode INode.FirstChild {
69
public abstract bool DoMatch(INode other, Match match);
71
public virtual bool DoMatchCollection(Role role, INode pos, Match match, BacktrackingInfo backtrackingInfo)
73
return DoMatch (pos, match);
76
public static bool DoMatchCollection(Role role, INode firstPatternChild, INode firstOtherChild, Match match)
78
BacktrackingInfo backtrackingInfo = new BacktrackingInfo();
79
Stack<INode> patternStack = new Stack<INode>();
80
Stack<PossibleMatch> stack = backtrackingInfo.backtrackingStack;
81
patternStack.Push(firstPatternChild);
82
stack.Push(new PossibleMatch(firstOtherChild, match.CheckPoint()));
83
while (stack.Count > 0) {
84
INode cur1 = patternStack.Pop();
85
INode cur2 = stack.Peek().NextOther;
86
match.RestoreCheckPoint(stack.Pop().Checkpoint);
88
while (cur1 != null && success) {
89
while (cur1 != null && cur1.Role != role)
90
cur1 = cur1.NextSibling;
91
while (cur2 != null && cur2.Role != role)
92
cur2 = cur2.NextSibling;
96
Debug.Assert(stack.Count == patternStack.Count);
97
success = cur1.DoMatchCollection(role, cur2, match, backtrackingInfo);
98
Debug.Assert(stack.Count >= patternStack.Count);
99
while (stack.Count > patternStack.Count)
100
patternStack.Push(cur1.NextSibling);
102
cur1 = cur1.NextSibling;
104
cur2 = cur2.NextSibling;
106
while (cur2 != null && cur2.Role != role)
107
cur2 = cur2.NextSibling;
108
if (success && cur2 == null)