Ejemplo n.º 1
0
        /// <summary>Find the rule to a RuleLink.</summary>
        /// <param name="rules"></param>
        /// <param name="link"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        private static Rule InitializeResolve(List <Rule> rules, RuleLink link, ParserStatus status)
        {
            Rule rule = rules.FirstOrDefault(r => r.Name == link.Value);

            if (rule == null)
            {
                status.AddBuildError(() => MessageRes.itc24, link.DefinitionCodeElement, link.Value);
            }
            return(rule);
        }
Ejemplo n.º 2
0
        /// <summary>Override this to set a property from grammar.</summary>
        /// <param name="property">CodeElement with property name.</param>
        /// <param name="value">Value string.</param>
        /// <param name="status">If error add to this.</param>
        /// <returns>True: property set. False: not set.</returns>
        public virtual bool SetProperty(CodeElement property, string value, ParserStatus status)
        {
            bool ok = false;

            foreach (ParserElementBase item in ChildNodes)
            {
                ok = ok | item.SetProperty(property, value, status);
            }

            return(ok);
        }
Ejemplo n.º 3
0
        private static bool ValidateGrammarElement(ParserElementBase elem, ParserStatus status)
        {
            bool ok = true;

            if (elem.ChildNodes == null)
            {
                return(ok);
            }
            foreach (ParserElementBase sub in elem.ChildNodes)
            {
                ok = ValidateGrammarElement(sub, status) && ok;
            }

            return(ok);
        }
Ejemplo n.º 4
0
        /// <summary>Apply settings to a linked Grammar.</summary>
        /// <returns></returns>
        internal static bool ValidateGrammar(Parser parser, ParserStatus status)
        {
            // Check first rule must represent all document. Tag = true
            bool ok = true;

            if (parser.Rules[0].Collapse)
            {
                status.AddBuildError(() => MessageRes.itc21, parser.Rules[0].DefinitionCodeElement, parser.Rules[0].Name);
                ok = false;
            }

            // Recursive check
            foreach (Rule rule in parser.Rules)
            {
                ok = ValidateGrammarElement(rule, status) && ok;
            }

            return(ok);
        }
Ejemplo n.º 5
0
        ///
        internal static bool BuildRules(Parser parser, CodeDocument doc, ParserStatus status)
        {
            parser.Rules = new List <Rule>();

            foreach (CodeElement ruleElement in doc.Codes(MetaParser.Rule_______))
            {
                string debug1 = "(" + parser.Name + ")".NL() + ruleElement.ToMarkupProtected("");

                List <CodeElement> ruleElements = ruleElement.Codes().ToList();
                CodeElement        elementId    = ruleElements.First();
                ruleElements.Remove(elementId);
                List <ParserElementBase> elements = BuildExpression(parser, ruleElements, status);
                Rule rule = AddRule(parser, elementId, elements.ToArray());

                string debug2 = debug1 + rule.GetGrammar();
            }

            parser.Rules[0].Comment = true;

            return(ApplySettingsFromGrammar(parser, doc, status) &&
                   InitializeGrammar(parser, parser.Rules, status) &&
                   ValidateGrammar(parser, status));
        }
Ejemplo n.º 6
0
        internal static Parser GetHardCodeParser(ParserStatus status)
        {
            List <Rule> list = new List <Rule>();

            // Build Parser in code.
            // grammar   = {rule} [settings];
            list.Add(new Rule(MetaGrammar_,
                              new Sequence(new RuleLink(Rule_______)),
                              new Optional(new RuleLink(Settings___)))
            {
                Comment = true
            });

            // rule = identifier '=' expression ';'
            list.Add(new Rule(Rule_______,
                              new WordIdent(),
                              new WordSymbol("="),
                              new RuleLink(Expression_),
                              new WordSymbol(";")));

            // expression = element {[or] element};
            list.Add(new Rule(Expression_,
                              new RuleLink(Element____),
                              new Sequence(
                                  new Optional(
                                      new RuleLink(Or_________)),
                                  new RuleLink(Element____)))
            {
                Collapse = true
            });

            // element    = identifier | symbol | block;
            list.Add(new Rule(Element____,
                              new Or(new WordIdent(),
                                     new Or(new RuleLink(WordSymbol_),
                                            new RuleLink(Block______))))
            {
                Collapse = true
            });

            // block      = sequence | optional | parentheses;
            list.Add(new Rule(Block______,
                              new Or(new RuleLink(Sequence___),
                                     new Or(new RuleLink(Optional___),
                                            new RuleLink(Parentheses))))
            {
                Collapse = true
            });

            // sequence     = '{' expression '}';
            list.Add(new Rule(Sequence___,
                              new WordSymbol("{"),
                              new RuleLink(Expression_),
                              new WordSymbol("}")));
            // optional     = '[' expression ']';
            list.Add(new Rule(Optional___,
                              new WordSymbol("["),
                              new RuleLink(Expression_),
                              new WordSymbol("]")));
            // parentheses      = '(' expression ')';
            list.Add(new Rule(Parentheses,
                              new WordSymbol("("),
                              new RuleLink(Expression_),
                              new WordSymbol(")")));
            // or         = '|';
            list.Add(new Rule(Or_________,
                              new WordSymbol("|")));

            // symbol       = string;
            list.Add(new Rule(WordSymbol_,
                              new WordString()));

            // settings   > 'settings' {setter};
            list.Add(new Rule(Settings___,
                              new WordSymbol(Settings___),
                              new Sequence(
                                  new RuleLink(Setter_____)))
            {
                Collapse = true
            });

            // setter     > identifier assignment {',' assignment} ';';
            list.Add(new Rule("setter",
                              new WordIdent(),
                              new RuleLink(Assignment_),
                              new Sequence(
                                  new WordSymbol(","),
                                  new RuleLink(Assignment_)),
                              new WordSymbol(";")));

            // assignment > property '=' value;
            list.Add(new Rule(Assignment_,
                              new RuleLink(Property___),
                              new Optional(
                                  new WordSymbol("="),
                                  new RuleLink(Value______))));


            // property   > identifier;
            list.Add(new Rule(Property___,
                              new WordIdent()));

            // value      > string;";
            list.Add(new Rule(Value______,
                              new WordString()));

            Parser parser = new Parser()
            {
                Level = 1
            };                                          // { Name = HardGrammar_ };

            parser.Rules = list;
            //foreach (var eq in list) eq.Parser = parser;
            ParserBuilder.InitializeGrammar(parser, parser.Rules, status);

            return(parser);
        }
Ejemplo n.º 7
0
        private static List <ParserElementBase> BuildExpression(Parser parser, IEnumerable <CodeElement> docNodes, ParserStatus status)
        {
            //string debug1 = "(" + parser.Name + ")".NL() + docNotes.Aggregate("", (s, n) => s + n.ToMarkupProtected(""));

            List <ParserElementBase> elements = new List <ParserElementBase>();

            foreach (CodeElement element in docNodes)
            {
                switch (element.Name)
                {
                case MetaParser.Expression_:
                    if (docNodes.Count() > 1)
                    {
                        status.AddBuildError(() => MessageRes.itc29, element, parser.Name);
                    }

                    return(BuildExpression(parser, element.Codes(), status));

                case MetaParser.Or_________:
                    ParserElementBase  el1, el2;
                    List <CodeElement> orNodes = docNodes.ToList();
                    // find position
                    int pos = 0;
                    while (pos + 2 < orNodes.Count() && orNodes[++pos] != element)
                    {
                    }
                    if (pos < 1 || pos + 2 > orNodes.Count())
                    {
                        status.AddBuildError(() => MessageRes.itc30, element, parser.Name);
                    }

                    if (pos == 1)
                    {
                        el1 = elements[0];
                    }
                    else
                    {
                        el1 = new SetOfElements(elements.ToArray());
                    }

                    var elementElements2 = new List <CodeElement>();
                    for (int i = pos + 1; i < orNodes.Count(); i++)
                    {
                        elementElements2.Add(orNodes[i]);
                    }
                    List <ParserElementBase> elements2 = BuildExpression(parser, elementElements2, status);

                    if (elements2.Count() == 1)
                    {
                        el2 = elements2[0];
                    }
                    else
                    {
                        el2 = new SetOfElements(elements2.ToArray());
                    }
                    return(new List <ParserElementBase> {
                        new Or(el1, el2)
                    });

                case MetaParser.WordIdent__:
                    ParserElementBase elem;
                    switch (element.Value)
                    {
                    case MetaParser.WordString_:
                        elem = new WordString();
                        break;

                    case MetaParser.WordInt____:
                        elem = new WordInt();
                        break;

                    case MetaParser.WordFloat__:
                        elem = new WordFloat();
                        break;

                    case MetaParser.WordIdent__:
                        elem = new WordIdent();
                        break;

                    case MetaParser.WordBool___:
                        elem = new WordBool();
                        break;

                    default:
                        elem = new RuleLink(element.Value);
                        elem.DefinitionCodeElement = element;
                        break;
                    }
                    elements.Add(elem);
                    break;

                case MetaParser.WordSymbol_:
                    elements.Add(new WordSymbol(element.Value));
                    break;

                case MetaParser.Sequence___:
                    elements.Add(new Sequence(BuildExpression(parser, element.Codes(), status).ToArray()));
                    break;

                case MetaParser.Optional___:
                    elements.Add(new Optional(BuildExpression(parser, element.Codes(), status).ToArray()));
                    break;

                case MetaParser.Parentheses:
                    elements.Add(new Parentheses(BuildExpression(parser, element.Codes(), status).ToArray()));
                    break;

                case MetaParser.Comment____:
                    break;

                default:
                    status.AddBuildError(() => MessageRes.itc31, element, element.Name);
                    break;
                }
            }
            return(elements);
        }
Ejemplo n.º 8
0
        /// <summary>Apply settings to a linked Grammar.</summary>
        /// <returns></returns>
        private static bool ApplySettingsFromGrammar(Parser parser, CodeDocument doc, ParserStatus status)
        {
            bool ok = true;

            foreach (CodeElement SetterElement in doc.Codes(MetaParser.Setter_____))
            {
                CodeElement elementId = SetterElement.Codes().First();

                Rule rule = parser.Rules.FirstOrDefault(r => r.Name == elementId.Value);
                if (rule == null)
                {
                    status.AddBuildError(() => MessageRes.itc26, elementId, elementId.Value);
                    ok = false;
                    continue;
                }

                foreach (CodeElement assignElement in SetterElement.Codes(MetaParser.Assignment_))
                {
                    List <CodeElement> assignNodes = assignElement.Codes().ToList();
                    CodeElement        propName    = assignNodes[0];
                    string             propValue   = assignNodes.Count > 1 ? assignNodes[1].Value : string.Empty;
                    switch (propName.Value)
                    {
                    case MetaParser.Trust______:
                        rule.Trust = propValue != "false";
                        break;

                    case MetaParser.Collapse___:
                        rule.Collapse = propValue != "false";
                        break;

                    case MetaParser.Comment____:
                        rule.Comment = propValue != "false";
                        break;

                    default:
                        // set the property on rule or sub elements.
                        ok = rule.SetProperty(propName, propValue, status);

                        if (!ok)
                        {
                            status.AddBuildError(() => MessageRes.itc27, propName, elementId.Value, propName.Value);
                        }
                        break;
                    }
                }
            }
            return(ok);
        }
Ejemplo n.º 9
0
 /// <summary>Initialize rules and elements. Called when creating a new parser and when cloning grammar.</summary>
 /// <param name="elements">Elements to Initialize.</param>
 /// <param name="rules">Set of rules.</param>
 /// <param name="status">The parser status.</param>
 private static void InitializeElements(IEnumerable <ParserElementBase> elements, List <Rule> rules, ParserStatus status)
 {
     if (elements == null || elements.Count() == 0)
     {
         return;
     }
     foreach (ParserElementBase element in elements)
     {
         var ruleId = element as RuleLink;
         if (ruleId != null && ruleId.RuleElement == null)
         {
             ruleId.RuleElement = InitializeResolve(rules, ruleId, status);
         }
         InitializeElements(element.ChildNodes, rules, status);
     }
 }
Ejemplo n.º 10
0
        /// <summary>Initialize rules and elements. Called when creating a new parser and when cloning grammar.</summary>
        /// <param name="parser">The parser.</param>
        /// <param name="rules">Set of rules.</param>
        /// <param name="status">The parser status.</param>
        /// <returns>True: no error. False: error.</returns>
        internal static bool InitializeGrammar(Parser parser, List <Rule> rules, ParserStatus status)
        {
            foreach (Rule rule in rules)
            {
                rule.Parser = parser;

                //string debug1 = "" + parser.Level + ": " + rule.GetGrammar().NL() +
                //    rule.ToMarkupProtected(string.Empty);

                if (rules.Any(r => r != rule && r.Name.ToLower() == rule.Name.ToLower()))
                {
                    status.AddBuildError(() => MessageRes.itc23, rule.DefinitionCodeElement,
                                         rule.Name,
                                         parser.Name);
                }
            }

            foreach (Rule rule in rules)
            {
                InitializeElements(rule.ChildNodes, rules, status);
            }

            // Transformation of syntax: Initialize expressions here
            foreach (Rule rule in rules)
            {
                Or         or     = rule.ChildNodes[0] as Or;
                WordSymbol symbol = null;
                Rule       ruleOp = null;
                if (or != null &&
                    Expression.IsBinaryAlternative(rule, or.ChildNodes[0], out symbol, out ruleOp))
                {
                    rule.ReplaceSubElement(0, new Expression(rule, or));
                }
            }

            if (status.Error == null)
            {
                // Loop check and set RuleLink.Recursive
                var effectiveRules = new List <Rule>();
                parser.Rules[0].InitializeLoop(effectiveRules, new List <ParserElementBase>(), status);

                parser.Rules[0].InitializeLoop(effectiveRules, new List <ParserElementBase>(), status);

                foreach (Rule rule in effectiveRules)
                {
                    if (!rule.LoopHasEnd)
                    {
                        status.AddBuildError(() => MessageRes.itc25, rule.DefinitionCodeElement, rule.Name);
                    }
                }

                foreach (Rule rule in effectiveRules)
                {
                    if (rule.LoopLeftRecursive)
                    {
                        status.AddBuildError(() => MessageRes.itc28, rule.DefinitionCodeElement, rule.Name);
                    }
                }
            }
            return(status.Error == null);
        }
Ejemplo n.º 11
0
 /// <summary>Find which RuleLinks are recursive.
 /// Called by the ParserFactory after Initializing grammar.
 /// Each path though the grammar must be followed, and each rule must have an ending.</summary>
 /// <param name="rules">Build list of analysed rules.</param>
 /// <param name="path">The path to the current element; only rules and RuleLinks.</param>
 /// <param name="status"></param>
 /// <returns>True: one path has an ending.</returns>
 public abstract bool InitializeLoop(List <Rule> rules, List <ParserElementBase> path, ParserStatus status);