예제 #1
0
        public void TestEncodeAndDecode(
            [Values(
                 ParserActionKind.Fail,
                 ParserActionKind.Accept,
                 ParserActionKind.Reduce,
                 ParserActionKind.Shift
                 )]
            ParserActionKind kind,
            [Values(0, 1, 1024, ushort.MaxValue)]
            int value1)
        {
            int cell = ParserAction.Encode(kind, value1);

            var action = ParserAction.Decode(cell);

            if (kind == ParserActionKind.Fail)
            {
                Assert.AreEqual(kind, action.Kind);
            }
            else
            {
                Assert.IsNotNull(action);
                Assert.AreEqual(kind, action.Kind);
                Assert.AreEqual(value1, action.Value1);
            }

            Assert.AreEqual(kind, ParserAction.GetKind(cell));
            Assert.AreEqual(value1, ParserAction.GetId(cell));
        }
예제 #2
0
        private bool TryResolveShiftReduce(int actionX, int actionY, int incomingToken, out int output)
        {
            output = 0;

            int shiftAction, reduceAction;

            if (ParserAction.IsShift(actionX) &&
                ParserAction.GetKind(actionY) == ParserActionKind.Reduce)
            {
                shiftAction  = actionX;
                reduceAction = actionY;
            }
            else if (ParserAction.IsShift(actionY) &&
                     ParserAction.GetKind(actionX) == ParserActionKind.Reduce)
            {
                shiftAction  = actionY;
                reduceAction = actionX;
            }
            else
            {
                // Unsupported conflict type. Use first action
                output = actionX;
                return(false);
            }

            var shiftTokenPrecedence = grammar.GetTermPrecedence(incomingToken);
            var reduceRulePrecedence = grammar.GetProductionPrecedence(ParserAction.GetId(reduceAction));

            if (shiftTokenPrecedence == null && reduceRulePrecedence == null)
            {
                // In case of conflict prefer shift over reduce
                output = shiftAction;
                return(false);
            }
            else if (shiftTokenPrecedence == null)
            {
                output = reduceAction;
            }
            else if (reduceRulePrecedence == null)
            {
                output = shiftAction;
            }
            else if (Precedence.IsReduce(reduceRulePrecedence, shiftTokenPrecedence))
            {
                output = reduceAction;
            }
            else
            {
                output = shiftAction;
            }

            return(true);
        }