/// <summary> /// Returns a ParseExpression by processing a suffix token. /// </summary> static object ProcessSuffix(Token token, ParseContext context, object[] args) { var expression = (ParseExpression)token[0].Tag; // Wrap the expression if a quantifier is present if (token.ChildCount > 1) { var quantifier = context.MatchedText(token[1]); if (quantifier.StartsWith("?")) return new Optional(expression); if (quantifier.StartsWith("*")) return new ZeroOrMore(expression); return new OneOrMore(expression); } return expression; }
/// <summary> /// Creates a SyntaxException with the specified parsing context and /// incomplete parse result. /// </summary> public SyntaxException(ParseContext context, Token result) : base(BuildErrorMessages(context)) { mContext = context; mResult = result; }
/// <summary> /// Returns a PatternTerminal by processing a literal token. /// </summary> static object ProcessRegexLiteral(Token token, ParseContext context, object[] args) { var pattern = context.MatchedText(token[0]); pattern = PatternTerminal.Unescape(pattern); return new PatternTerminal(pattern); }
/// <summary> /// Returns a ParseExpression by processing a sequence token. /// </summary> static object ProcessSequence(Token token, ParseContext context, object[] args) { // Unwrap sequences of only one nested expression and use as-is if (token.ChildCount == 1) return token[0].Tag; // Otherwise, build a proper sequence from the nested children var expressions = new List<ParseExpression>(); for (var i = 0; i < token.ChildCount; ++i) expressions.Add((ParseExpression)token[i].Tag); return new Sequence(expressions.ToArray()); }
/// <summary> /// Returns a ParseExpression by processing a prefix token. /// </summary> static object ProcessPrefix(Token token, ParseContext context, object[] args) { // Wrap the expression with a predicate if a prefix is present if (token.ChildCount > 1) { var expression = (ParseExpression)token[1].Tag; if (token[0].Matched("AND")) return new Match(expression); return new NotMatch(expression); } // Otherwise, return the raw expression return token[0].Tag; }
/// <summary> /// Returns a ParseExpression by processing a primary token. /// </summary> static object ProcessPrimary(Token token, ParseContext context, object[] args) { if (token.ChildCount == 1) { var firstChild = token[0].Tag; // Primary is an identifier - wrap it as a rule reference if (firstChild is string) return new RuleRef(firstChild.ToString()); // Primary is a literal - propagate it return firstChild; } // Primary is a nested expression - propagate it return token[1].Tag; }
/// <summary> /// Returns a terminal expression by processing a literal token. /// </summary> static object ProcessLiteral(Token token, ParseContext context, object[] args) { return token[0].Tag; }
/// <summary> /// Returns a ParseExpression by processing an ordered choice token. /// </summary> static object ProcessOrderedChoice(Token token, ParseContext context, object[] args) { // Form an ordered choice if multiple sequences are present if (token.ChildCount > 1) { var choiceExpressions = new List<ParseExpression>(); for (var i = 0; i < token.ChildCount; ++i) { var child = token[i].Tag as ParseExpression; if (child != null) choiceExpressions.Add(child); } return new OrderedChoice(choiceExpressions.ToArray()); } // Otherwise, just return the first sequence return token[0].Tag; }
/// <summary> /// Returns a Parser by processing a grammar token. /// </summary> static object ProcessGrammar(Token token, ParseContext context, object[] args) { var grammarConstructs = new List<GrammarConstruct>(); foreach (var rule in token.Children.Select(c => c.Tag).OfType<ParseRule>()) grammarConstructs.Add(rule); foreach (var arg in args) grammarConstructs.Add((CustomMatcher)arg); return new Parser<Token>((t, ctx, parseArgs) => t, (ParseRule)grammarConstructs.First(), grammarConstructs.Skip(1).ToArray()); }
/// <summary> /// Returns an identifier string by processing an identifier token. /// </summary> static object ProcessIdentifier(Token token, ParseContext context, object[] args) { return context.MatchedText(token[0]); }
/// <summary> /// Returns a ParseExpression by processing an expression token. /// </summary> static object ProcessExpression(Token token, ParseContext context, object[] args) { return token[0].Tag; }
/// <summary> /// Returns a ParseRule by processing a definition token. /// </summary> static object ProcessDefinition(Token token, ParseContext context, object[] args) { var ruleName = token[0].Tag.ToString(); var expr = (ParseExpression)token[2].Tag; return new ParseRule(ruleName, expr); }
/// <summary> /// Returns a CustomMatcherTerminal by processing a custom matcher /// literal token. /// </summary> static object ProcessCustomMatcher(Token token, ParseContext context, object[] args) { var matcherName = context.MatchedText(token[0]); matcherName = matcherName.Substring(1, matcherName.Length - 2); return new CustomMatcherTerminal(matcherName); }
internal ParseError(Token token, ParseExpression expected) { mToken = token; mExpected = expected; }
internal Token Add(Token token) { // Unwrap anonymous nested tokens and add their children directly if (token.Anonymous && token.HasChildren) { if (mChildren == null) mChildren = token.mChildren; else mChildren.AddRange(token.mChildren); } // Otherwise, add the token as a nested child else { if (mChildren == null) mChildren = new List<Token>(4); mChildren.Add(token); } return this; }