예제 #1
0
        public Parser <TToken, TRule> Rule(
            TRule type,
            params Action <IParserRuleConfigurator <TToken, TRule> >[] options)
        {
            if (this.configCompleted)
            {
                throw ParserConfigurationException.AlreadyCompleted();
            }

            if (!this.rulesByType.TryGetValue(type, out var rule))
            {
                rule = new RuleDefinition(type);
                this.rulesByType.Add(type, rule);
            }

            foreach (var option in options)
            {
                option(rule);
            }

            return(this);
        }
예제 #2
0
        public Parser <TToken, TRule> WithRoot(TRule type)
        {
            if (this.configCompleted)
            {
                throw ParserConfigurationException.AlreadyCompleted();
            }

            this.rootType        = type;
            this.configCompleted = true;

            // Validate the configuration to ensure
            // no expected rules are missing
            var validated  = new HashSet <TRule>();
            var toValidate = new Stack <TRule>();

            toValidate.Push(type);
            while (toValidate.Count != 0)
            {
                var checking = toValidate.Pop();
                if (!this.rulesByType.TryGetValue(checking, out var checkingDefinition))
                {
                    throw ParserConfigurationException.RuleNotDefined(checking.ToString());
                }

                validated.Add(checking);
                foreach (var dependency in checkingDefinition
                         .DirectlyDependsOn()
                         .Where(o => !validated.Contains(o))
                         .Distinct())
                {
                    toValidate.Push(dependency);
                }
            }

            return(this);
        }