public void IntegerLexTest() { ILexRule intRule = new SimpleLexRule(LexMatchType.LitInt, "[0-9]+"); string source = "834"; string expected = "834"; ILexResult result = intRule.Match(source); Assert.AreEqual(result.Text, expected); }
public void WhitespeceLexTest() { ILexRule whitespaceRule = new SimpleLexRule(LexMatchType.LitInt, "\\s+"); string source = " 834 "; string expected = " "; ILexResult result = whitespaceRule.Match(source); Assert.AreEqual(expected, result.Text); }
public static bool IsInside(this ILexResultGroup group, ILexResult target) { int targetEnd = target.GetEnd(); if ((target.Start >= group.Start && target.Start <= group.GetEnd()) && (targetEnd >= group.Start && targetEnd <= group.GetEnd())) { return(true); } else { return(false); } }
public void StringLexTest() { ILexRule stringQuotRule = new SimpleLexRule(LexMatchType.LitStringQuot, "(?<!\\\\)\""); ILexRule escapeQuotRule = new SimpleLexRule(LexMatchType.LitStringEscape, "\\\""); ContainerLexRule stringRule = new ContainerLexRule(LexMatchType.LitString, stringQuotRule, stringQuotRule); stringRule.Add(escapeQuotRule); string source = " \"I am a string!\" "; string expected = "\"I am a string!\""; ILexResult result = stringRule.Match(source); Assert.AreEqual(expected, result.Text); }
public void FloatLexTest() { ILexRule intRule = new SimpleLexRule(LexMatchType.LitInt, "[0-9]+"); SequenceLexRule floatRule = new SequenceLexRule(LexMatchType.LitFloat); floatRule.Add(intRule); floatRule.Add(new SimpleLexRule(LexMatchType.LitFloatSep, "\\.")); floatRule.Add(intRule); string source = " 452.39 "; string expected = "452.39"; ILexResult result = floatRule.Match(source); Assert.AreEqual(expected, result.Text); }
public static bool OverlapsAt(this ILexResult result, int position, int length) { int end = position + length; // has some length if (length > 0) { return((position >= result.Start && position < result.GetEnd()) || (end > result.Start && end <= result.GetEnd())); } // zero-length nodes else if (length == 0) { return(position > result.Start && position < result.GetEnd()); } // negative lengths canceled else { throw new InvalidOperationException("Negative lengths not allowed."); } }
public IParseResult Parse(ILexResult target) { if (!Accepts(target)) { return(ParseResult.Empty); } ASTNode containerNode = new ASTNode(target); containerNode.MatchType = MatchType; IParseResultGroup resultGroup = new ParseResultGroup(ParseStatus.Success, containerNode); Action <IParseResult> prAdder = pr => { if (pr.Status != ParseStatus.None && pr.Node.MatchType != ParseMatchType.None) { containerNode.Add(pr.Node); resultGroup.Add(pr); } }; foreach (IParseRule rule in _parseRules) { if (target is ILexResultGroup) { ILexResultGroup targetGroup = target as ILexResultGroup; foreach (ILexResult lexResult in targetGroup) { IParseResult parseResult = rule.Parse(lexResult); prAdder(parseResult); } } else { IParseResult parseResult = rule.Parse(target); prAdder(parseResult); } } return(resultGroup); }
public void EmptyLexTest() { ILexRule nullRule = new FunctionalLexRule( LexMatchType.Null, target => { if (string.IsNullOrEmpty(target)) { return(new LexNode(LexMatchType.Null, 0, "")); } else { return(LexNode.NoMatch); } } ); string source = ""; string expected = ""; ILexResult result = nullRule.Match(source); Assert.AreEqual(result.Text, expected); }
public void BoolLexTest() { ILexRule boolRule = new UnionLexRule(LexMatchType.LitBool, new ILexRule[] { // true pattern new SimpleLexRule(LexMatchType.LitBool, "\\btrue\\b"), // false pattern new SimpleLexRule(LexMatchType.LitBool, "\\bfalse\\b") }); string source = " true "; string expected = "true"; ILexResult result = boolRule.Match(source); Assert.AreEqual(result.Text, expected); source = " false "; expected = "false"; result = boolRule.Match(source); Assert.AreEqual(expected, result.Text); }
public static bool IsPartial(this ILexResult result) { return(result.MatchType == LexMatchType.Partial); }
public static bool IsUnmatched(this ILexResult result) { return(result.MatchType == LexMatchType.None); }
public static bool IsSuccessful(this ILexResult result) { return(result.MatchType != LexMatchType.None && result.MatchType != LexMatchType.Invalid); }
public static int GetEnd(this ILexResult result) { return(result.Start + result.Length); }
public bool Accepts(ILexResult target) { return(Validator(target)); }
public static bool Overlaps(this ILexResult result, ILexResult target) { return(result.OverlapsAt(target.Start, target.Length)); }
public static bool IsInvalid(this ILexResult result) { return(result.MatchType == LexMatchType.Invalid); }
public ILexResult Match(string target) { // if no rules, no match if (_rules.Count == 0) { return(LexNode.NoMatch); } LexResultGroup group = new LexResultGroup(MatchType); group.RequiresFilledSpace = true; // get first match, then offset ILexResult firstResult = _rules[0].Match(target); if (!firstResult.IsSuccessful()) { return(LexNode.NoMatch); } string eaten = target.Clone() as string; group.Start = firstResult.Start; group.Add(firstResult); // eat the string until after the match eaten = eaten.Remove(0, firstResult.GetEnd()); int offset = firstResult.GetEnd(); // go through each match after the first for (int i = 1; i < Count; i++) { ILexResult result = _rules[i].Match(eaten); // ensure all pieces in the sequence succeed if (result.IsSuccessful()) { // matches must be "squared up" if (result.Start != 0) { // wrap group as a partial result return(LayeredLexNode.CreatePartial(group)); } else { // eat the string eaten = eaten.Remove(0, result.GetEnd()); // store an offset copy to the group group.Add(result.Offset(offset)); // offset the offset offset += result.GetEnd(); } } else if (result.MatchType == LexMatchType.Invalid) { return(result.Offset(offset)); } else { return(LexNode.NoMatch); } } return(group); }
public static bool Overlaps(this ILexResultGroup group, ILexResult target) { return(group.OverlapsAt(target.Start, target.Length)); }