Пример #1
0
        public void ShouldMapRuleNamesToRules()
        {
            var ruleA = new ParseRule("RuleA", new LiteralTerminal("a"));
            var ruleB = new ParseRule("RuleB", new LiteralTerminal("b"));

            var parser = new Parser<Token>(null, ruleA, ruleB);

            Assert.Equal(ruleA, parser.GetRule(ruleA.Name));
            Assert.Equal(ruleB, parser.GetRule(ruleB.Name));
        }
Пример #2
0
 public virtual ParseState ApplyRules(ParseRule[] rules, ref string input)
 {
     foreach (var rule in rules)
     {
         var m = rule.Match(input);
         if (m.Success)
         {
             input = input.Substring(m.Length);
             return rule.Apply(this, m);
         }
     }
     var message = input.Length <= 20 ? input : input.Remove(20) + "...";
     return new ErrorState(this, Level, $"Unknown syntax: {message}");
 }
Пример #3
0
 public virtual ParseState ApplyRules(ParseRule[] rules, ref string input, ref int lineNumber)
 {
     foreach (var rule in rules)
     {
         var m = rule.Match(input);
         if (m.Success)
         {
             input = input.Substring(m.Length);
             lineNumber += m.Value.Count(ch => ch == '\n');
             return rule.Apply(this, m);
         }
     }
     var message = string.Join(Environment.NewLine, input.Split('\n').Take(3));
     return new ErrorState(this, Level, $"Unknown syntax at line {lineNumber}:{Environment.NewLine}{message}");
 }
Пример #4
0
        protected ParseRule Spaced(ParseRule rule)
        {
            return () => {

                Whitespace ();

                var result = ParseObject(rule);
                if (result == null) {
                    return null;
                }

                Whitespace ();

                return result;
            };
        }
Пример #5
0
 public static TocViewModel LoadToc(string tocContent, string filePath)
 {
     ParseState state = new InitialState(filePath);
     var rules = new ParseRule[]
     {
         new TopicTocParseRule(),
         new ExternalLinkTocParseRule(),
         new ContainerParseRule(),
         new CommentParseRule(),
         new WhitespaceParseRule(),
     };
     var content = tocContent;
     while (content.Length > 0)
     {
         state = state.ApplyRules(rules, ref content);
     }
     return state.Root;
 }
Пример #6
0
 public static TocViewModel LoadToc(string tocContent, string filePath)
 {
     ParseState state = new InitialState(filePath);
     var rules = new ParseRule[]
     {
         new TopicTocParseRule(),
         new ExternalLinkTocParseRule(),
         new TopicXrefAutoLinkTocParseRule(),
         new TopicXrefShortcutTocParseRule(),
         new ContainerParseRule(),
         new CommentParseRule(),
         new WhitespaceParseRule(),
     };
     var content = tocContent.Replace("\r\n", "\n").Replace("\r", "\n");
     int lineNumber = 1;
     while (content.Length > 0)
     {
         state = state.ApplyRules(rules, ref content, ref lineNumber);
     }
     return state.Root;
 }
Пример #7
0
        public static TocViewModel LoadToc(string tocContent, string filePath)
        {
            ParseState state = new InitialState(filePath);
            var        rules = new ParseRule[]
            {
                new TopicTocParseRule(),
                new ExternalLinkTocParseRule(),
                new TopicXrefAutoLinkTocParseRule(),
                new TopicXrefShortcutTocParseRule(),
                new ContainerParseRule(),
                new CommentParseRule(),
                new WhitespaceParseRule(),
            };
            var content    = tocContent.Replace("\r\n", "\n").Replace("\r", "\n");
            int lineNumber = 1;

            while (content.Length > 0)
            {
                state = state.ApplyRules(rules, ref content, ref lineNumber);
            }
            return(state.Root);
        }
        protected List <Expression> ExpressionFunctionCallArguments()
        {
            if (ParseString("(") == null)
            {
                return(null);
            }

            // "Exclude" requires the rule to succeed, but causes actual comma string to be excluded from the list of results
            ParseRule commas    = Exclude(String(","));
            var       arguments = Interleave <Expression>(Expression, commas);

            if (arguments == null)
            {
                arguments = new List <Expression> ();
            }

            Whitespace();

            Expect(String(")"), "closing ')' for function call");

            return(arguments);
        }
Пример #9
0
        internal override bool Parse(ParseContext context, ParseRule rule, out Token result)
        {
            SequenceMemento state;
            if (context.Recovering)
                state = (SequenceMemento)context.Recover();
            else
                state = new SequenceMemento(context);

            context.BeginExpression(state);

            // Parse each subexpression to find nested tokens
            for (; state.Index < ExpressionCount; ++state.Index) {
                var expr = Expression(state.Index);
                Token t;

                // Parsing failed on a subexpression - return an overall failure
                if (!expr.Parse(context, rule, out t)) {
                    context.Offset = state.Offset;
                    context.EndExpression();
                    result = t;
                    return false;
                }

                // Skip blank tokens
                if (t.Blank)
                    continue;

                // Add the parsed token to our result
                state.Result.Add(t);
            }

            if (state.Result.HasChildren)
                state.Result.EndOffset = context.Offset;

            context.EndExpression();

            result = state.Result;
            return true;
        }
Пример #10
0
        protected List <T> SeparatedList <T> (SpecificParseRule <T> mainRule, ParseRule separatorRule) where T : class
        {
            T firstElement = Parse(mainRule);

            if (firstElement == null)
            {
                return(null);
            }

            var allElements = new List <T> ();

            allElements.Add(firstElement);

            do
            {
                int nextElementRuleId = BeginRule();

                var sep = separatorRule();
                if (sep == null)
                {
                    FailRule(nextElementRuleId);
                    break;
                }

                var nextElement = Parse(mainRule);
                if (nextElement == null)
                {
                    FailRule(nextElementRuleId);
                    break;
                }

                SucceedRule(nextElementRuleId);

                allElements.Add(nextElement);
            } while (true);

            return(allElements);
        }
Пример #11
0
    private void Binary()
    {
        // Remember the operator.
        TokenType operatorType = parser.previous.type;

        // Compile the right operand.
        ParseRule rule = GetRule(operatorType);

        ParsePrecedence((Precedence)(rule.precedence + 1)); // hehehee

        // Emit the operator instruction.
        switch (operatorType)
        {
        case TokenType.BANG_EQUAL: EmitBytes(OpCode.EQUAL, OpCode.NOT); break;

        case TokenType.EQUAL_EQUAL: EmitByte(OpCode.EQUAL); break;

        case TokenType.GREATER: EmitByte(OpCode.GREATER); break;

        case TokenType.GREATER_EQUAL: EmitBytes(OpCode.LESS, OpCode.NOT); break;     // >= is the same as !(<)

        case TokenType.LESS: EmitByte(OpCode.LESS); break;

        case TokenType.LESS_EQUAL: EmitBytes(OpCode.GREATER, OpCode.NOT); break;     // <= is the same as !(>)

        case TokenType.PLUS: EmitByte(OpCode.ADD); break;

        case TokenType.MINUS: EmitByte(OpCode.SUBTRACT); break;

        case TokenType.STAR: EmitByte(OpCode.MULTIPLY); break;

        case TokenType.SLASH: EmitByte(OpCode.DIVIDE); break;

        default:
            return;     // Unreachable.
        }
    }
Пример #12
0
        public void ProgramRuleTest()
        {
            LexResultGroup lexedSource = _testLexer.Lex("\"I have a \\\"thing\\\" for you.\" 33.45");

            ParseRule expressionRule = new ParseRule(
                l => l.MatchType != LexMatchType.Whitespace && l.MatchType != LexMatchType.None,
                l => new ParseResult(ParseStatus.Success, new ASTNode(ParseMatchType.Expression, l))
                );
            ParseRule ignoreRule = new ParseRule(
                l => l.MatchType == LexMatchType.Whitespace,
                l => new ParseResult(ParseStatus.Success, new ASTNode(ParseMatchType.Ignore, l))
                );
            ParseRule unlexedRule = new ParseRule(
                l => l.MatchType == LexMatchType.None,
                l => DetailedParseResult.CreateError(
                    new ASTNode(ParseMatchType.Invalid, l),
                    $"Unlexed token `{l.Text}' detected at character {l.Start}."
                    )
                );

            ContainerParseRule programRule = new ContainerParseRule(ParseMatchType.Program, LexMatchType.Program);

            programRule.Add(unlexedRule);
            programRule.Add(expressionRule);
            programRule.Add(ignoreRule);

            IParseResult result = programRule.Parse(lexedSource);

            Assert.AreEqual("\"I have a \\\"thing\\\" for you.\"", result.Node[0].Text);
            Assert.IsTrue(result.Node[0].MatchType == ParseMatchType.Expression);

            Assert.AreEqual(" ", result.Node[1].Text);
            Assert.IsTrue(result.Node[1].MatchType == ParseMatchType.Ignore);

            Assert.AreEqual("33.45", result.Node[2].Text);
            Assert.IsTrue(result.Node[2].MatchType == ParseMatchType.Expression);
        }
Пример #13
0
        public List <object> OneOrMore(ParseRule rule)
        {
            var results = new List <object> ();

            object result = null;

            do
            {
                result = ParseObject(rule);
                if (result != null)
                {
                    results.Add(result);
                }
            } while(result != null);

            if (results.Count > 0)
            {
                return(results);
            }
            else
            {
                return(null);
            }
        }
Пример #14
0
 public DelimCtx(string delim, string name = null, string desc = null, ParseRule parseRule = null,
                 string ctx = null, bool start = false, bool end = false, SyntaxRequirement addReq = null, bool printable = true, bool breaking = true)
     : base(delim, name, desc, parseRule, addReq, printable, breaking)
 {
     contextName = ctx; isStart = start; isEnd = end;
 }
Пример #15
0
        void GenerateStatementLevelRules()
        {
            var levels = Enum.GetValues(typeof(StatementLevel)).Cast <StatementLevel> ().ToList();

            _statementRulesAtLevel      = new ParseRule[levels.Count][];
            _statementBreakRulesAtLevel = new ParseRule[levels.Count][];

            foreach (var level in levels)
            {
                List <ParseRule> rulesAtLevel  = new List <ParseRule> ();
                List <ParseRule> breakingRules = new List <ParseRule> ();

                // Diverts can go anywhere
                rulesAtLevel.Add(Line(MultiDivert));

                if (level >= StatementLevel.Top)
                {
                    // Knots can only be parsed at Top/Global scope
                    rulesAtLevel.Add(KnotDefinition);
                    rulesAtLevel.Add(ExternalDeclaration);
                }

                rulesAtLevel.Add(Line(Choice));

                rulesAtLevel.Add(Line(AuthorWarning));

                // Gather lines would be confused with multi-line block separators, like
                // within a multi-line if statement
                if (level > StatementLevel.InnerBlock)
                {
                    rulesAtLevel.Add(Gather);
                }

                // Stitches (and gathers) can (currently) only go in Knots and top level
                if (level >= StatementLevel.Knot)
                {
                    rulesAtLevel.Add(StitchDefinition);
                }

                // Global variable declarations can go anywhere
                rulesAtLevel.Add(Line(VariableDeclaration));
                rulesAtLevel.Add(Line(ConstDeclaration));

                // Global include can go anywhere
                rulesAtLevel.Add(Line(IncludeStatement));

                // Normal logic / text can go anywhere
                rulesAtLevel.Add(LogicLine);
                rulesAtLevel.Add(LineOfMixedTextAndLogic);

                // --------
                // Breaking rules

                // Break current knot with a new knot
                if (level <= StatementLevel.Knot)
                {
                    breakingRules.Add(KnotDeclaration);
                }

                // Break current stitch with a new stitch
                if (level <= StatementLevel.Stitch)
                {
                    breakingRules.Add(StitchDeclaration);
                }

                // Breaking an inner block (like a multi-line condition statement)
                if (level <= StatementLevel.InnerBlock)
                {
                    breakingRules.Add(ParseDashNotArrow);
                    breakingRules.Add(String("}"));
                }

                _statementRulesAtLevel [(int)level]      = rulesAtLevel.ToArray();
                _statementBreakRulesAtLevel [(int)level] = breakingRules.ToArray();
            }
        }
Пример #16
0
        /**
         * Parse a rule and, if succcessful, put the result into the provided list.
         */
        internal static bool ParseIntoList <T>(ref ParserPosition position, List <T> result, ParseRule <T> rule)
        {
            T obj;

            if (rule(ref position, out obj))
            {
                result.Add(obj);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #17
0
        private static ParseRule GetRuleByXPath(HtmlNodeWithUrl[] nodesarr, string label, bool collectIMGTags, bool collectLINKTags, bool collectMETATags, System.Drawing.Size? minSize = null)
        {
            ParseRule result = null;

            if (nodesarr != null && nodesarr.Length > 0)
            {
                #region ByXPath
                string mask1 = string.Empty;
                string mask2 = string.Empty;

                string[] xpaths = nodesarr.Select(n => n.Node.XPath).ToArray();
                mask1 = LongestMaskedPathBetween(xpaths);
                mask2 = LongestMaskedStringBetween(xpaths);

                if (
                        nodesarr
                            .Select(n => new { Node = n.Node.OwnerDocument.DocumentNode, Url = n.Url })
                            .Select(nodeItem =>
                                {
                                    var links = Helper
                                                .GetAllImagesUrlsFromUrl(nodeItem.Node.OwnerDocument, nodeItem.Url.AbsoluteUri, collectIMGTags, collectLINKTags, collectMETATags, null)
                                                .Where(n => Helper.StringLikes(n.Node.XPath, mask1));
                                    return
                                        minSize == null
                                        ? links.Count()
                                        : Helper.GetAllImagesUrlsWithMinSize(links.ToArray(), minSize.Value).Count();
                                }
                            )
                            .Where(c => c != 1)
                            .Count() == 0)
                    result = new ParseRule()
                    {
                        Label = label,
                        Condition = ParseFindRuleCondition.ByXPath,
                        Parameter = mask1
                    };

                if (
                        nodesarr
                            .Select(n => new { Node = n.Node.OwnerDocument.DocumentNode, Url = n.Url })
                            .Select(nodeItem =>
                                {
                                    var links = Helper
                                                .GetAllImagesUrlsFromUrl(nodeItem.Node.OwnerDocument, nodeItem.Url.AbsoluteUri, collectIMGTags, collectLINKTags, collectMETATags, null)
                                                .Where(n => Helper.StringLikes(n.Node.XPath, mask2));
                                    return
                                        minSize == null
                                        ? links.Count()
                                        : Helper.GetAllImagesUrlsWithMinSize(links.ToArray(), minSize.Value).Count();
                                }
                            )
                            .Where(c => c != 1)
                            .Count() == 0)
                    result = new ParseRule()
                    {
                        Label = label,
                        Condition = ParseFindRuleCondition.ByXPath,
                        Parameter = mask2
                    };

                #endregion
                #region ByXPathAndIndex
                if (result == null)
                {
                    string betterMask = mask2;
                    int index =
                        nodesarr
                            .Select(n => new { Doc = n.Node.OwnerDocument, Node = n.Node.OwnerDocument.DocumentNode, Url = n.Url })
                            .Select(n =>
                                {
                                    var links = Helper
                                            .GetAllImagesUrlsFromUrl(n.Node.OwnerDocument, n.Url.AbsoluteUri, collectIMGTags, collectLINKTags, collectMETATags, null)
                                            .Where(i => Helper.StringLikes(i.Node.XPath, betterMask));

                                    string[] images =
                                        (minSize == null
                                            ? links.ToArray()
                                            : Helper.GetAllImagesUrlsWithMinSize(links.ToArray(), minSize.Value)
                                        )
                                        .Select(i => i.Url.AbsoluteUri)
                                        .ToArray();

                                    for (int i = 0; i < images.Length; i++)
                                        if (images[i].ToLower() == n.Url.AbsoluteUri.ToLower())
                                            return i;
                                    return -1;
                                }
                            ).Distinct().OrderBy( i => i).FirstOrDefault();
                    if (index != -1)
                        result = new ParseRule()
                        {
                            Label = label,
                            Condition = ParseFindRuleCondition.ByXPathAndIndex,
                            Parameter = betterMask + ";" + index.ToString()
                        };
                }
                #endregion
            }

            if (result != null)
            {
                result.CheckImageSize = minSize != null ? true : false;
                if (minSize != null)
                    result.MinImageSize = minSize.Value;
                result.CollectIMGTags = collectIMGTags;
                result.CollectLINKTags = collectLINKTags;
                result.CollectMETATags = collectMETATags;
            }

            if (minSize != null && result == null)
            {
                System.Drawing.Size minCalcedSize = new System.Drawing.Size();

                foreach (var sz in Helper.GetImageSizes(nodesarr.Select(n => new SomeNodeElement() { Node = n.Node, Url = n.Url }).ToArray()).Select(n => n.Value))
                {
                    if (minCalcedSize.Width > sz.Width)
                        minCalcedSize.Width = sz.Width;
                    if (minCalcedSize.Height > sz.Height)
                        minCalcedSize.Height = sz.Height;
                }

                if (minSize.Value.Height < minCalcedSize.Height || minSize.Value.Width < minCalcedSize.Width)
                    result = GetRuleByLink(nodesarr, label, collectIMGTags, collectLINKTags, collectMETATags, minCalcedSize);
            }

            return result;
        }
Пример #18
0
        protected Parsed.Object LogicLine()
        {
            Whitespace();

            if (ParseString("~") == null)
            {
                return(null);
            }

            Whitespace();

            // Some example lines we need to be able to distinguish between:
            // ~ temp x = 5  -- var decl + assign
            // ~ temp x      -- var decl
            // ~ x = 5       -- var assign
            // ~ x           -- expr (not var decl or assign)
            // ~ f()         -- expr
            // We don't treat variable decl/assign as an expression since we don't want an assignment
            // to have a return value, or to be used in compound expressions.
            ParseRule afterTilda = () => OneOf(ReturnStatement, TempDeclarationOrAssignment, Expression);

            var result = Expect(afterTilda, "expression after '~'", recoveryRule: SkipToNextLine) as Parsed.Object;

            // Parse all expressions, but tell the writer off if they did something useless like:
            //  ~ 5 + 4
            // And even:
            //  ~ false && myFunction()
            // ...since it's bad practice, and won't do what they expect if
            // they're expecting C's lazy evaluation.
            if (result is Expression && !(result is FunctionCall || result is IncDecExpression))
            {
                // TODO: Remove this specific error message when it has expired in usefulness
                var varRef = result as VariableReference;
                if (varRef && varRef.name == "include")
                {
                    Error("'~ include' is no longer the correct syntax - please use 'INCLUDE your_filename.ink', without the tilda, and in block capitals.");
                }

                else
                {
                    Error("Logic following a '~' can't be that type of expression. It can only be something like:\n\t~ return\n\t~ var x = blah\n\t~ x++\n\t~ myFunction()");
                }
            }

            // A function call on its own line could result in a text side effect, in which case
            // it needs a newline on the end. e.g.
            //  ~ printMyName()
            // If no text gets printed, then the extra newline will have to be culled later.
            if (result is FunctionCall)
            {
                // Add extra pop to make sure we tidy up after ourselves - we no longer need anything on the evaluation stack.
                var funCall = result as FunctionCall;
                funCall.shouldPopReturnedValue = true;

                result = new ContentList(funCall, new Parsed.Text("\n"));
            }

            Expect(EndOfLine, "end of line", recoveryRule: SkipToNextLine);

            return(result as Parsed.Object);
        }
Пример #19
0
        internal override bool Parse(ParseContext context, ParseRule rule, out Token result)
        {
            OrderedChoiceMemento state;
            if (context.Recovering)
                state = (OrderedChoiceMemento)context.Recover();
            else
                state = new OrderedChoiceMemento(context);

            context.BeginExpression(state);

            // Parse each subexpression until the first match
            for (; state.index < ExpressionCount; ++state.index) {
                var expr = Expression(state.index);
                Token t;

                // Parsing succeeded on a subexpression - return the result
                if (expr.Parse(context, rule, out t)) {
                    context.EndExpression();
                    result = t;
                    return true;
                }

                context.Offset = state.offset;
            }

            context.EndExpression();

            return context.Reject(rule, this, out result);
        }
Пример #20
0
 public Exception(ParseRule rule) : base(rule.Descriptor + " could not be executed on input")
 {
     AllErrors.AddRange(rule.errorInfo);
     LastErrors.AddRange(rule.LastErrors);
     Rule = rule;
 }
Пример #21
0
		void GenerateStatementLevelRules()
		{
            var levels = Enum.GetValues (typeof(StatementLevel)).Cast<StatementLevel> ().ToList();

            _statementRulesAtLevel = new ParseRule[levels.Count][];
            _statementBreakRulesAtLevel = new ParseRule[levels.Count][];

            foreach (var level in levels) {
                List<ParseRule> rulesAtLevel = new List<ParseRule> ();
                List<ParseRule> breakingRules = new List<ParseRule> ();

                // Diverts can go anywhere
                rulesAtLevel.Add(Line(MultiDivert));

                if (level >= StatementLevel.Top) {

                    // Knots can only be parsed at Top/Global scope
                    rulesAtLevel.Add (KnotDefinition);
                    rulesAtLevel.Add (ExternalDeclaration);
                }

                rulesAtLevel.Add(Line(Choice));

                rulesAtLevel.Add(Line(AuthorWarning));

                // Gather lines would be confused with multi-line block separators, like
                // within a multi-line if statement
                if (level > StatementLevel.InnerBlock) {
                    rulesAtLevel.Add (Gather);
                }

                // Stitches (and gathers) can (currently) only go in Knots and top level
                if (level >= StatementLevel.Knot) {
                    rulesAtLevel.Add (StitchDefinition);
                }

                // Global variable declarations can go anywhere
                rulesAtLevel.Add(Line(VariableDeclaration));
                rulesAtLevel.Add(Line(ConstDeclaration));

                // Global include can go anywhere
                rulesAtLevel.Add(Line(IncludeStatement));

                // Normal logic / text can go anywhere
                rulesAtLevel.Add(LogicLine);
                rulesAtLevel.Add(LineOfMixedTextAndLogic);

                // --------
                // Breaking rules

                // Break current knot with a new knot
                if (level <= StatementLevel.Knot) {
                    breakingRules.Add (KnotDeclaration);
                }

                // Break current stitch with a new stitch
                if (level <= StatementLevel.Stitch) {
                    breakingRules.Add (StitchDeclaration);
                }

                // Breaking an inner block (like a multi-line condition statement)
                if (level <= StatementLevel.InnerBlock) {
                    breakingRules.Add (ParseDashNotArrow);
                    breakingRules.Add (String ("}"));
                }

                _statementRulesAtLevel [(int)level] = rulesAtLevel.ToArray ();
                _statementBreakRulesAtLevel [(int)level] = breakingRules.ToArray ();
            }
		}
Пример #22
0
        // Content text is an unusual parse rule compared with most since it's
        // less about saying "this is is the small selection of stuff that we parse"
        // and more "we parse ANYTHING except this small selection of stuff".
        protected string ContentTextNoEscape()
        {
            // Eat through text, pausing at the following characters, and
            // attempt to parse the nonTextRule.
            // "-": possible start of divert or start of gather
            // "<": possible start of glue
            if (_nonTextPauseCharacters == null)
            {
                _nonTextPauseCharacters = new CharacterSet("-<");
            }

            // If we hit any of these characters, we stop *immediately* without bothering to even check the nonTextRule
            // "{" for start of logic
            // "|" for mid logic branch
            if (_nonTextEndCharacters == null)
            {
                _nonTextEndCharacters       = new CharacterSet("{}|\n\r\\#");
                _notTextEndCharactersChoice = new CharacterSet(_nonTextEndCharacters);
                _notTextEndCharactersChoice.AddCharacters("[]");
                _notTextEndCharactersString = new CharacterSet(_nonTextEndCharacters);
                _notTextEndCharactersString.AddCharacters("\"");
            }

            // When the ParseUntil pauses, check these rules in case they evaluate successfully
            ParseRule nonTextRule = () => OneOf(ParseDivertArrow, ParseThreadArrow, EndOfLine, Glue);

            CharacterSet endChars = null;

            if (parsingStringExpression)
            {
                endChars = _notTextEndCharactersString;
            }
            else if (_parsingChoice)
            {
                endChars = _notTextEndCharactersChoice;
            }
            else
            {
                endChars = _nonTextEndCharacters;
            }

            string pureTextContent = ParseUntil(nonTextRule, _nonTextPauseCharacters, endChars);

            //Mohan
            if (!_parsingChoice)
            {
                string agent_dialog = pureTextContent;
                if (agent_dialog != null)
                {
                    int count = Agent_Dialogs.Count;
                    Agent_Dialogs.Add(count, agent_dialog);
                }
            }
            //Mohan


            if (pureTextContent != null)
            {
                return(pureTextContent);
            }
            else
            {
                return(null);
            }
        }
Пример #23
0
 private void FinishApplyingRules(string value, ParseRule pr, ref List<string> singleVals, ref List<string> expandedVals)
 {
     if (pr.Expand && !string.IsNullOrEmpty(pr.Delimiter))
     {
         var format = string.IsNullOrEmpty(pr.Format) ? "D" : pr.Format;
         var vals = value.Split(new[] { pr.Delimiter }, StringSplitOptions.RemoveEmptyEntries).ToList();
         //for an integer range, fill in the middle values
         int a, b;
         if (vals.Count() == 2 && int.TryParse(vals[0], out a) && int.TryParse(vals[1], out b))
         {
             var lower = a + 1;
             var upper = b;
             if (pr.Modulo > 0 && upper < lower)
                 upper += pr.Modulo;
             var lastVal = vals[1];
             vals.RemoveAt(1);
             for (int i = lower; i < upper; i++)
             {
                 var newVal = pr.Modulo > 0 ? i % pr.Modulo : i;
                 vals.Add(newVal.ToString(format));
             }
             vals.Add(lastVal);
         }
         expandedVals.AddRange(vals);
     }
     else
         singleVals.Add(value);
 }
Пример #24
0
 public override ParseState ApplyRules(ParseRule[] rules, ref string input, ref int lineNumber)
 {
     throw new DocumentException($"Invalid toc file: {FilePath}, Details: {Message}");
 }
Пример #25
0
        public List <T> Interleave <T>(ParseRule ruleA, ParseRule ruleB, ParseRule untilTerminator = null, bool flatten = true)
        {
            int ruleId = BeginRule();

            var results = new List <T> ();

            // First outer padding
            var firstA = ParseObject(ruleA);

            if (firstA == null)
            {
                return((List <T>)FailRule(ruleId));
            }
            else
            {
                TryAddResultToList(firstA, results, flatten);
            }

            object lastMainResult = null, outerResult = null;

            do
            {
                // "until" condition hit?
                if (untilTerminator != null && Peek(untilTerminator) != null)
                {
                    break;
                }

                // Main inner
                lastMainResult = ParseObject(ruleB);
                if (lastMainResult == null)
                {
                    break;
                }
                else
                {
                    TryAddResultToList(lastMainResult, results, flatten);
                }

                // Outer result (i.e. last A in ABA)
                outerResult = null;
                if (lastMainResult != null)
                {
                    outerResult = ParseObject(ruleA);
                    if (outerResult == null)
                    {
                        break;
                    }
                    else
                    {
                        TryAddResultToList(outerResult, results, flatten);
                    }
                }

                // Stop if there are no results, or if both are the placeholder "ParseSuccess" (i.e. Optional success rather than a true value)
            } while((lastMainResult != null || outerResult != null) &&
                    !(lastMainResult == ParseSuccess && outerResult == ParseSuccess) && remainingLength > 0);

            if (results.Count == 0)
            {
                return((List <T>)FailRule(ruleId));
            }

            return((List <T>)SucceedRule(ruleId, results));
        }
Пример #26
0
 public DelimOp(string delim, string name = null, string desc = null, ParseRule parseRule = null, SyntaxRequirement addReq = null, int order = 100, SyntaxGenerator syntax = null, TokenResolver resolve = null, bool printable = true, bool breaking = true)
     : base(delim, name, desc, parseRule, addReq, printable, breaking)
 {
     this.order = order; isSyntaxValid = syntax; this.resolve = resolve;
 }
Пример #27
0
        private void UpdateStep(int step, bool action, bool clear = false, byte insideThreadCount = 3)
        {
            if (clear)
                UrlsToAddList.Clear();

            #region step 1
            if (step == 1 && action)
            {
                object lockAdd = new Object();
                UrlsToAddList.Clear();

#if DEBUG
                insideThreadCount = 1;
#else
                insideThreadCount = ThreadCount;
#endif

                ParseRuleConnectionType type = NewParseRule.Connection;

                int minWidth = NewParseRule.MinImageWidth;
                int minHeight = NewParseRule.MinImageHeight;
                bool collectIMGTags = NewParseRule.CollectIMGTags;
                bool collectLINKTags = NewParseRule.CollectLINKTags;
                bool collectMETATags = NewParseRule.CollectMETATags;
                byte threadCount = this.ThreadCount;

                BackgroundWorker bw = new BackgroundWorker();
                bw.DoWork += (s, e) =>
                    {
                        Helpers.PercentageProgress progress = new Helpers.PercentageProgress();
                        progress.Change += (sP, eP) =>
                            {
                                bw.ReportProgress((int)eP.Value);
                            };

                        List<UrlResultWrapper> urlResultWrapper = new List<UrlResultWrapper>();
                        var urls = e.Argument as StringUrlWithResultWrapper[];

                        if (urls != null)
                            urls
                                .Where(item => item != null && !string.IsNullOrWhiteSpace(item.Value) && Helper.IsWellFormedUriString(item.Value, UriKind.Absolute))
                                .Select(sw => 
                                    new 
                                        { 
                                            item = sw,
                                            prgItem = progress.GetChild() 
                                        })
                                .ToArray()
                                .AsParallel()
                                .WithDegreeOfParallelism(insideThreadCount)
                                .ForAll(
                                    (sw) =>
                                    {
                                        var item = new UrlResultWrapper() { Value = sw.item.Value };

                                        System.Drawing.Size minSize = new System.Drawing.Size() { Width = minWidth, Height = minHeight };

                                        var result = Helper.GetAllImagesFromUrl(item.Value, minSize, collectIMGTags, collectLINKTags, collectMETATags, threadCount, sw.prgItem, true, type);

                                        foreach (ParseImageResult res in result)
                                            item.ParseResult.Add(res);

                                        if (item.ParseResult.Count > 0)
                                            lock (lockAdd)
                                            {
                                                urlResultWrapper.Add(item);
                                            }
                                    });

                        e.Result = urlResultWrapper;
                    };
                bw.RunWorkerCompleted += (s, e) =>
                    {
                        if (e.Error != null)
                            throw e.Error;

                        try
                        {
                            List<UrlResultWrapper> urlResultWrapper = e.Result as List<UrlResultWrapper>;
                            foreach (var item in urlResultWrapper)
                            {
                                if (item.ParseResult != null)
                                    foreach (var ps in item.ParseResult)
                                        ps.IsSelected = (item.ParseResult.IndexOf(ps) == 0);
                                
                                UrlsToAddList.Add(item);
                            }
                        }
                        finally
                        {
                            bw.Dispose();
                            IsBusy = false;
                        }
                    };
                bw.WorkerReportsProgress = true;
                bw.ProgressChanged += (s, e) =>
                    {
                        LoadedPercent = e.ProgressPercentage;
                    };
                IsBusy = true;
                bw.RunWorkerAsync(Urls.ToArray());
                while (bw.IsBusy)
                    Helper.DoEvents();
                bw = null;
            }
#endregion
#region step 2
            else if (step == 2 && action)
            {
                HtmlNodeWithUrl[] nodes =
                    UrlsToAddList
                    .Where(n => !string.IsNullOrWhiteSpace(n.Value))
                    .Select(i => 
                        {
                            ParseImageResult res = i.ParseResult.Where(i2 => i2.IsSelected).FirstOrDefault();
                            return
                                new HtmlNodeWithUrl()
                                {
                                    Node = res == null ? null : res.Node,
                                    Url = res == null ? new Uri(i.Value, UriKind.RelativeOrAbsolute) : res.Url
                                };
                        }
                    )
                    .Where(i3 => i3 != null && i3.Node != null)
                    .ToArray();

                ParseRule newRule = Helper.GetRule(nodes, NewParseRule.Label, NewParseRule.MinImageSize, NewParseRule.CollectIMGTags, NewParseRule.CollectLINKTags, NewParseRule.CollectMETATags);
                newRule.CopyObject(NewParseRule, new string[] { "Connection" });

                ShowRuleModeCommand.Execute(null);
            }
#endregion

            if (step >= UrlsToAddTabControl.Items.Count)
                for (int i = UrlsToAddTabControl.Items.Count - 1; i >= 0; i--)
                    (UrlsToAddTabControl.Items[i] as TabItem).Visibility = (i == UrlsToAddTabControl.Items.Count - 1) ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
            else if (step < 0)
                for (int i = UrlsToAddTabControl.Items.Count - 1; i >= 0; i--)
                    (UrlsToAddTabControl.Items[i] as TabItem).Visibility = (i == 0) ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
            else
            { 
                for (int i = UrlsToAddTabControl.Items.Count - 1; i >= 0; i--)
                    (UrlsToAddTabControl.Items[i] as TabItem).Visibility = (i == step) ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
            }

            UrlsToAddTabControl.SelectedIndex = UrlsToAddTabControl.Items.IndexOf(UrlsToAddTabControl.Items.Cast<TabItem>().FirstOrDefault(ti => ti.Visibility == System.Windows.Visibility.Visible));
        }
Пример #28
0
        public string ParseUntil(ParseRule stopRule, CharacterSet pauseCharacters = null, CharacterSet endCharacters = null)
        {
            int ruleId = BeginRule();


            CharacterSet pauseAndEnd = new CharacterSet();

            if (pauseCharacters != null)
            {
                pauseAndEnd.UnionWith(pauseCharacters);
            }
            if (endCharacters != null)
            {
                pauseAndEnd.UnionWith(endCharacters);
            }

            StringBuilder parsedString      = new StringBuilder();
            object        ruleResultAtPause = null;

            // Keep attempting to parse strings up to the pause (and end) points.
            //  - At each of the pause points, attempt to parse according to the rule
            //  - When the end point is reached (or EOF), we're done
            do
            {
                // TODO: Perhaps if no pause or end characters are passed, we should check *every* character for stopRule?
                string partialParsedString = ParseUntilCharactersFromCharSet(pauseAndEnd);
                if (partialParsedString != null)
                {
                    parsedString.Append(partialParsedString);
                }

                // Attempt to run the parse rule at this pause point
                ruleResultAtPause = Peek(stopRule);

                // Rule completed - we're done
                if (ruleResultAtPause != null)
                {
                    break;
                }
                else
                {
                    if (endOfInput)
                    {
                        break;
                    }

                    // Reached a pause point, but rule failed. Step past and continue parsing string
                    char pauseCharacter = currentCharacter;
                    if (pauseCharacters != null && pauseCharacters.Contains(pauseCharacter))
                    {
                        parsedString.Append(pauseCharacter);
                        if (pauseCharacter == '\n')
                        {
                            lineIndex++;
                        }
                        index++;
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
            } while(true);

            if (parsedString.Length > 0)
            {
                return((string)SucceedRule(ruleId, parsedString.ToString()));
            }
            else
            {
                return((string)FailRule(ruleId));
            }
        }
Пример #29
0
 public override ParseState ApplyRules(ParseRule[] rules, ref string input)
 {
     throw new InvalidDataException($"Invalid toc file: {FilePath}, Details: {Message}");
 }
Пример #30
0
		// Modifier to turn a rule into one that expects a newline on the end.
		// e.g. anywhere you can use "MixedTextAndLogic" as a rule, you can use 
		// "Line(MixedTextAndLogic)" to specify that it expects a newline afterwards.
		protected ParseRule Line(ParseRule inlineRule)
		{
			return () => {
				object result = ParseObject(inlineRule);
                if (result == null) {
                    return null;
                }

				Expect(EndOfLine, "end of line", recoveryRule: SkipToNextLine);

				return result;
			};
		}
Пример #31
0
 public Delim(string delim, string name = null, string desc = null, ParseRule parseRule = null, SyntaxRequirement addReq = null, bool printable = true, bool breaking = true)
 {
     text = delim; this.name = name; description = desc; this.parseRule = parseRule; extraReq = addReq; this.printable = printable; this.breaking = breaking;
 }