示例#1
0
        public ReduceShiftPrecedence(SymbolCoordinates coords, AssociativityEnum associativity,
                                     IEnumerable <PrecedenceWord> inputTokens,
                                     IEnumerable <PrecedenceWord> conflictProds)
            : base(coords, associativity, inputTokens.Concat(conflictProds))
        {
            try
            {
                InputSet     = inputTokens.ToArray();
                ReduceSymbol = conflictProds.First();
                ShiftSymbols = conflictProds.Skip(1).ToArray();

                if (ShiftSymbols.Count() < 1)
                {
                    throw new Exception();
                }
            }
            catch
            {
                throw ParseControlException.NewAndRun("Incorrect shift/reduce precedence rule");
            }
        }
示例#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);
        }