Beispiel #1
0
        public static Precedence Create(SymbolCoordinates coords, string mode, string associativity, IEnumerable <string> inputSymbols,
                                        IEnumerable <PrecedenceWord> conflictProds)
        {
            precedenceMode prec = getPrec(mode);

            AssociativityEnum assoc = getAssoc(associativity);

            switch (prec)
            {
            case precedenceMode.Operator: return(new OperatorPrecedence(coords, assoc, inputSymbols.Select(it => new PrecedenceWord(it)), conflictProds));

            case precedenceMode.ReduceShift: return(new ReduceShiftPrecedence(coords, assoc, inputSymbols.Select(it => new PrecedenceWord(it)), conflictProds));

            case precedenceMode.ReduceReduce: return(new ReduceReducePrecedence(coords, assoc, inputSymbols.Select(it => new PrecedenceWord(it)), conflictProds));
            }

            throw ParseControlException.NewAndRun("Not recognized precedence");
        }
Beispiel #2
0
        internal static IEnumerable <Precedence> CreateOperators(SymbolCoordinates coords, string mode, IEnumerable <Tuple <string, string> > __opPairs,
                                                                 // it can be single and then serves as both reduce production and shift production
                                                                 // or it can be many, but then remember to put reduce production as first one (exactly as in RS rule)
                                                                 IEnumerable <string> __conflictProds)
        {
            if (!__conflictProds.Any())
            {
                throw ParseControlException.NewAndRun("There has to be at least one production given for operator precedence.");
            }

            string reduce_prod = __conflictProds.First();
            IEnumerable <string> shift_prod = __conflictProds.Count() == 1 ? new [] { __conflictProds.Single() }: __conflictProds.Skip(1).ToArray();

            precedenceMode prec = getPrec(mode);

            if (prec != precedenceMode.ReduceShift)
            {
                throw ParseControlException.NewAndRun("Only shift-reduce mode is supported with this syntax.");
            }

            Tuple <string, string>[] op_pairs = __opPairs.ToArray();
            var result = new List <Precedence>();

            for (int i = 0; i < op_pairs.Length; ++i)
            {
                string input_sym = op_pairs[i].Item2;

                var group = new List <Precedence>();

                {
                    // same vs same
                    // here we go as given associativity, because priority is the same (of course)
                    AssociativityEnum assoc = getAssoc(op_pairs[i].Item1);
                    group.Add(new ReduceShiftPrecedence(coords, assoc,
                                                        new[] { new PrecedenceWord(input_sym) },
                                                        PrecedenceWord.Create(reduce_prod, input_sym).Concat(shift_prod.Select(it => new PrecedenceWord(it))))
                    {
                        PriorityGroupEnd = false, PriorityGroupStart = false
                    });
                }

                if (i > 0)
                {
                    // higher priority means that if master is in input we shift, and when it is on stack we reduce
                    group.Add(new ReduceShiftPrecedence(coords, AssociativityEnum.Reduce,
                                                        op_pairs.Take(i).Select(it => new PrecedenceWord(it.Item2)),
                                                        PrecedenceWord.Create(reduce_prod, input_sym).Concat(shift_prod.Select(it => new PrecedenceWord(it))))
                    {
                        PriorityGroupEnd = false, PriorityGroupStart = false
                    });
                    group.Add(new ReduceShiftPrecedence(coords, AssociativityEnum.Shift,
                                                        new[] { new PrecedenceWord(input_sym) },
                                                        new PrecedenceWord(reduce_prod, op_pairs.Take(i).Select(it => it.Item2)).Concat(shift_prod.Select(it => new PrecedenceWord(it))))
                    {
                        PriorityGroupEnd = false, PriorityGroupStart = false
                    });
                }

                group.First().PriorityGroupStart = true;
                group.Last().PriorityGroupEnd    = true;

                result.AddRange(group);
            }

            return(result);
        }