Exemplo n.º 1
0
        public override ParseAction ParseAction(State state, ITerminalSymbol symbol)
        {
            if (state.IsEmpty)
            {
                return(SyntaxError);
            }

            // If any of the rules allow a shift, do that (ignoring potential reduces)
            if (state.items.Any(i => !i.AtEnd))
            {
                // TODO: Count shift/reduce conflicts
                // Shift the symbol onto the stack
                return((token, parser) => parser.Shift(token, state.terminalGotos[symbol.TerminalIndex]));
            }

            // We have one reduce rule
            if (state.items.Count == 1 && state.items.First().AtEnd)
            {
                // This is a "reduce" action
                return((token, parser) => state.items.First().Rule.function(token, parser));
            }

            // We have more than one reduce rule:
            throw new ReduceReduceConflict(state.items.First().Rule, state.items.ElementAt(1).Rule);
        }
Exemplo n.º 2
0
        public State CreateInitialState(INonterminalSymbol s)
        {
            // Hack to find the "eof" symbol
            ITerminalSymbol eof = (ITerminalSymbol)s.Rules.First().rhs[1];

            var state = new State();

            foreach (var rule in s.Rules)
            {
                state.items.Add(new Item(rule, 0, eof));
            }

            return(state);
        }
Exemplo n.º 3
0
 // Holds if the terminal can start this rule
 public bool Starts(ITerminalSymbol terminal)
 {
     foreach (var s in rhs)
     {
         if (s.First.Contains(terminal))
         {
             return(true);
         }
         if (!s.CanBeEmpty)
         {
             return(false);
         }
     }
     return(false);
 }
Exemplo n.º 4
0
        public ParseAction ParseAction(State state, ITerminalSymbol symbol)
        {
            if (state.IsEmpty)
            {
                return(Error);
            }

            var matchingItems = state.items.Where(i => i.AtEnd && i.Lookahead[0] == symbol);

            if (matchingItems.Count() == 1)
            {
                if (symbol.IsEof)
                {
                    return (token, parser) =>
                           {
                               matchingItems.Single().Rule.function(token, parser);
                               parser.ParseSuccess = true;
                           }
                }
                ;

                state.ValidInputs[symbol.TerminalIndex] = true;

                return((token, parser) => matchingItems.Single().Rule.function(token, parser));
            }

            if (matchingItems.Count() > 1)
            {
                throw new ReduceReduceConflict(matchingItems.ElementAt(0).Rule, matchingItems.ElementAt(1).Rule);
            }

            var targetState = state.terminalGotos[symbol.TerminalIndex];

            if (targetState.IsEmpty)
            {
                // This is a syntax error.
                // The valid gotos are given in the state.terminalGotos
                // Bug: This excludes symbols that could be shifted following a reduction.
                // therefore this doesn't really work...
                return((token, parser) => parser.SyntaxError(token));
            }

            state.ValidInputs[symbol.TerminalIndex] = true;

            // Default is to shift the symbol onto the stack
            return((token, parser) => parser.Shift(token, state.terminalGotos[symbol.TerminalIndex]));
        }
    }
Exemplo n.º 5
0
        public virtual ParseAction ParseAction(State state, ITerminalSymbol symbol)
        {
            if (state.IsEmpty)
            {
                return(SyntaxError);
            }

            // Are any of the items "reduce"
            if (state.items.Count == 1 && state.items.First().AtEnd)
            {
                if (symbol.IsEof)
                {
                    return (token, parser) =>
                           {
                               state.items.First().Rule.function(token, parser);
                               parser.ParseSuccess = true;
                           }
                }
                ;

                // This is a "reduce" action
                return((token, parser) => state.items.First().Rule.function(token, parser));
            }

            var atEndRules = state.items.Where(i => i.AtEnd);

            if (atEndRules.Count() > 1)
            {
                throw new ReduceReduceConflict(atEndRules.First().Rule, atEndRules.ElementAt(1).Rule);
            }

            // Detect shift/reduce conflict
            if (state.items.Count > 1 && atEndRules.Count() == 1)
            {
                // A shift/reduce conflict
                throw new ShiftReduceConflict(state.items.Where(i => !i.AtEnd).First().Rule, atEndRules.First().Rule);
            }

            // Shift the symbol onto the stack
            return((token, parser) => parser.Shift(token, state.terminalGotos[symbol.TerminalIndex]));
        }
Exemplo n.º 6
0
 public void Delete(ITerminalSymbol terminalSymbol)
 {
     terminalSymbols.Remove(terminalSymbol);
 }
Exemplo n.º 7
0
 public void Add(ITerminalSymbol graphic)
 {
     terminalSymbols.Add(graphic);
 }