|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Robin
{
public enum Status
{
Rejected = 0,
Initializing = 1,
Shifting = 2,
Accepted = 4,
}
public class Pattern
{
public static Pattern NullPattern = Pattern.of(Definition.NullDefinition,true);
public static Pattern of(Definition definition)
{
return of(definition,false);
}
public static Pattern of(Definition definition, bool leaf)
{
return new Pattern(definition, leaf);
}
protected Definition definition = null;
protected Guid identifier = Guid.NewGuid();
protected List<Signal> sequence = null;
protected SignalTree tree = null;
protected int position = 0;
protected bool accepted = false;
protected bool recursing = false;
protected bool shifting = false;
protected bool leaf = false;
public virtual SignalTree Tree
{
get
{
return this.tree;
}
}
public virtual bool IsLeaf
{
get
{
return this.leaf;
}
}
public virtual bool Recursing
{
get
{
return this.recursing;
}
set
{
this.recursing = value;
}
}
public virtual bool Accepted
{
get
{
return this.accepted;
}
set
{
this.accepted = value;
}
}
public virtual bool Shifting
{
get
{
return this.shifting;
}
set
{
this.shifting = value;
}
}
public virtual Guid Identifier
{
get
{
return this.identifier;
}
}
public virtual Signal Target
{
get
{
return this.definition.Target;
}
}
public virtual Definition Definition
{
get
{
return this.definition;
}
}
public virtual List<Signal> Sequence
{
get
{
return this.sequence ?? (this.sequence = new List<Signal>());
}
}
public virtual int Position
{
get
{
return this.position;
}
}
public virtual bool IsOptional
{
get
{
return this.Sequence.Count == 0;
}
}
public virtual bool IsRecursive
{
get
{
if (!this.IsOptional)
{
return this.Sequence[0].Match(this.Target);
}
return false;
}
}
public virtual bool IsSimpleRecursive
{
get
{
return this.IsRecursive && this.Sequence.Count == 2;
}
}
public virtual bool IsSignleton
{
get
{
if (!this.IsOptional)
{
return this.Sequence.Count == 1;
}
return false;
}
}
public virtual bool IsComplete
{
get
{
return !this.IsOptional && (this.position == this.Sequence.Count - 1);
}
}
public virtual bool IsDot
{
get
{
return !this.IsLeaf && this.IsSignleton && this.Sequence[0].Match(this.Target);
}
}
public virtual bool IsCurrentOptional
{
get
{
if (this.position >= 0 && this.position < this.Sequence.Count)
{
Signal s = this.Sequence[this.position];
Definition sd = this.Definition.Aggregation.GetDefinition(s);
if (sd != null && sd.IsOptional)
{
return true;
}
}
return false;
}
}
public Pattern(Definition definition, bool leaf)
{
if ((this.definition = definition) == null) throw new ArgumentNullException("definition");
this.leaf = leaf;
}
protected Pattern(Pattern p)
{
if (p != null)
{
this.definition = p.definition;
this.sequence = p.sequence;
this.position = p.position;
this.shifting = p.shifting;
this.recursing = p.recursing;
this.accepted = p.accepted;
//this.leaf = p.leaf;
//NOTICE: do not copy guid.
}
}
public virtual Definition PeekNextNonOptional()
{
int steps = 0;
this.PeekNonOptional(out steps);
return this.PeekNonOptional(this.position + steps + 1, out steps);
}
public virtual Definition PeekNonOptional()
{
int steps = 0;
return this.PeekNonOptional(out steps);
}
public virtual Definition PeekNonOptional(out int steps)
{
return this.PeekNonOptional(this.position, out steps);
}
public virtual Definition PeekNonOptional(int position,out int steps)
{
steps = 0;
position = position >= 0 ? position : 0;
for (int p = position; p < this.Sequence.Count; p++)
{
Signal s = this.Sequence[p];
Definition sd = this.Definition.Aggregation.GetDefinition(s);
if (sd != null && !sd.IsOptional)
{
return sd;
}
steps++;
}
return null;
}
public virtual bool Shift()
{
if (this.shifting)
{
this.shifting = false;
this.Advance();
return true;
}
return false;
}
public virtual void Advance(int steps)
{
for (int i = 0; i < steps; i++)
{
this.Advance();
}
}
public virtual void Advance()
{
int endpoint = this.Sequence.Count -1;
if (this.position < endpoint)
{
this.position++;
}
else //last position
{
this.position = 0;
}
}
public virtual Status Accept(Signal s)
{
Status acceptance = Status.Rejected;
if (this.position < this.Sequence.Count && this.position>=0)
{
Signal t = this.Sequence[this.position];
if (t.Match(s))
{
acceptance = (this.position < this.Sequence.Count - 1) ?
((this.position == 0) ? Status.Initializing : Status.Shifting) : Status.Accepted;
}
}
return acceptance;
}
public virtual bool RecursivelyEquals(Pattern pattern)
{
if (pattern != null)
{
if (this.IsRecursive && pattern.Sequence.Count == this.Sequence.Count-1)
{
bool equals = true;
for (int i = 1; i < this.Sequence.Count; i++)
{
if (!this.Sequence[i].Match(pattern.Sequence[i-1]))
{
equals = false;
break;
}
}
return equals;
}
}
return false;
}
public virtual bool GetLeaf(ref Signal s)
{
if (this.IsLeaf)
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < this.Sequence.Count; i++)
{
builder.Append(this.Sequence[i].Value);
}
s = Signal.of(builder.ToString(),true);
return true;
}
return false;
}
public virtual Pattern Clone()
{
return new Pattern(this);
}
public virtual Pattern Clone(Signal s, int position, SignalPrefix prefix)
{
Pattern p = new Pattern(this);
if (p != null)
{
p.tree = SignalTree.of(p,s,position, prefix);
}
return p;
}
public override string ToString()
{
StringBuilder builder = new StringBuilder();
if (builder != null)
{
int last = this.Sequence.Count - 1;
for (int i = 0; i <= last; i++)
{
Signal s = this.Sequence[i];
builder.AppendFormat("{0}", s.ToString());
if (i < last)
{
builder.Append(" ");
}
}
}
return builder.ToString();
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.