示例#1
0
        /// <summary>
        /// Parses the input and returns the produced AST
        /// </summary>
        /// <returns>AST produced by the parser representing the input, or null if unrecoverable errors were encountered</returns>
        public override ParseResult Parse()
        {
            reductions = new Queue <Reduction>();
            shifts     = new Queue <Shift>();
            int Ui = gss.CreateGeneration();
            int v0 = gss.CreateNode(0);

            nextToken = lexer.GetNextToken(this);

            // bootstrap the shifts and reductions queues
            int count = parserAutomaton.GetActionsCount(0, nextToken.TerminalID);

            for (int i = 0; i != count; i++)
            {
                LRAction action = parserAutomaton.GetAction(0, nextToken.TerminalID, i);
                if (action.Code == LRActionCode.Shift)
                {
                    shifts.Enqueue(new Shift(v0, action.Data));
                }
                else if (action.Code == LRActionCode.Reduce)
                {
                    reductions.Enqueue(new Reduction(v0, parserAutomaton.GetProduction(action.Data), SPPF.EPSILON));
                }
            }

            while (nextToken.TerminalID != Symbol.SID_EPSILON)             // Wait for ε token
            {
                // the stem length (initial number of nodes in the generation before reductions)
                int stem = gss.GetGeneration(Ui).Count;
                // apply all reduction actions
                Reducer(Ui);
                // no scheduled shift actions?
                if (shifts.Count == 0)
                {
                    // the next token was not expected
                    OnUnexpectedToken(stem);
                    return(new ParseResult(new ROList <ParseError>(allErrors), lexer.Input));
                }
                // look for the next next-token
                Lexer.TokenKernel oldtoken = nextToken;
                nextToken = lexer.GetNextToken(this);
                // apply the scheduled shift actions
                Ui = Shifter(oldtoken);
            }

            GSSGeneration genData = gss.GetGeneration(Ui);

            for (int i = genData.Start; i != genData.Start + genData.Count; i++)
            {
                int state = gss.GetRepresentedState(i);
                if (parserAutomaton.IsAcceptingState(state))
                {
                    // Has reduction _Axiom_ -> axiom $ . on ε
                    GSSPath[] paths = gss.GetPaths(i, 2, out count);
                    return(new ParseResult(new ROList <ParseError>(allErrors), lexer.Input, sppf.GetTree(paths[0][1])));
                }
            }
            // At end of input but was still waiting for tokens
            return(new ParseResult(new ROList <ParseError>(allErrors), lexer.Input));
        }
示例#2
0
文件: GSS.cs 项目: sebgod/hime
        /// <summary>
        /// Creates a new edge in the GSS
        /// </summary>
        /// <param name="from">The edge's starting node</param>
        /// <param name="to">The edge's target node</param>
        /// <param name="label">The edge's label</param>
        public void CreateEdge(int from, int to, int label)
        {
            edges.Add(new GSSEdge(from, to, label));
            GSSGeneration data = edgeGenerations[generation];

            data.Count++;
            edgeGenerations[generation] = data;
        }
示例#3
0
文件: GSS.cs 项目: sebgod/hime
        /// <summary>
        /// Prints this stack with the specified writer
        /// </summary>
        /// <param name="writer">A text writer</param>
        public void PrintTo(TextWriter writer)
        {
            // list of all nodes having at least one child
            List <int> linked = new List <int>();

            for (int i = generation; i != -1; i--)
            {
                writer.WriteLine("--- generation {0} ---", i);
                // Retrieve the edges in this generation
                Dictionary <int, List <int> > myedges = new Dictionary <int, List <int> >();
                GSSGeneration cedges = edgeGenerations[i];
                for (int j = 0; j != cedges.Count; j++)
                {
                    GSSEdge edge = edges[cedges.Start + j];
                    if (!myedges.ContainsKey(edge.From))
                    {
                        myedges.Add(edge.From, new List <int>());
                    }
                    myedges[edge.From].Add(edge.To);
                    if (!linked.Contains(edge.To))
                    {
                        linked.Add(edge.To);
                    }
                }
                // Retrieve the nodes in this generation and reverse their order
                GSSGeneration cnodes  = nodeGenerations[i];
                List <int>    mynodes = new List <int>();
                for (int j = 0; j != cnodes.Count; j++)
                {
                    mynodes.Add(cnodes.Start + j);
                }
                mynodes.Reverse();
                // print this generation
                foreach (int node in mynodes)
                {
                    string mark = linked.Contains(node) ? "node" : "head";
                    if (myedges.ContainsKey(node))
                    {
                        foreach (int to in myedges[node])
                        {
                            int gen = GetGenerationOf(to);
                            if (gen == i)
                            {
                                writer.WriteLine("\t{0} {1} to {2}", mark, nodeLabels[node], nodeLabels[to]);
                            }
                            else
                            {
                                writer.WriteLine("\t{0} {1} to {2} in gen {3}", mark, nodeLabels[node], nodeLabels[to], gen);
                            }
                        }
                    }
                    else
                    {
                        writer.WriteLine("\t{0} {1}", mark, nodeLabels[node]);
                    }
                }
            }
        }
示例#4
0
文件: GSS.cs 项目: sebgod/hime
        /// <summary>
        /// Creates a new node in the GSS
        /// </summary>
        /// <param name="state">The GLR state represented by the node</param>
        /// <returns>The node's identifier</returns>
        public int CreateNode(int state)
        {
            int           node = nodeLabels.Add(state);
            GSSGeneration data = nodeGenerations[generation];

            data.Count++;
            nodeGenerations[generation] = data;
            return(node);
        }
示例#5
0
文件: GSS.cs 项目: sebgod/hime
 /// <summary>
 /// Retrieve the generation of the given node in this GSS
 /// </summary>
 /// <param name="node">A node's index</param>
 /// <returns>The index of the generation containing the node</returns>
 private int GetGenerationOf(int node)
 {
     for (int i = generation; i != -1; i--)
     {
         GSSGeneration gen = nodeGenerations[i];
         if (node >= gen.Start && node < gen.Start + gen.Count)
         {
             return(i);
         }
     }
     // should node happen
     return(-1);
 }
示例#6
0
文件: GSS.cs 项目: sebgod/hime
        /// <summary>
        /// Finds in the given generation a node representing the given GLR state
        /// </summary>
        /// <param name="generation">A generation</param>
        /// <param name="state">A GLR state</param>
        /// <returns>The node representing the GLR state, or -1 if it is not found</returns>
        public int FindNode(int generation, int state)
        {
            GSSGeneration data = nodeGenerations[generation];

            for (int i = data.Start; i != data.Start + data.Count; i++)
            {
                if (nodeLabels[i] == state)
                {
                    return(i);
                }
            }
            return(-1);
        }
示例#7
0
文件: GSS.cs 项目: sebgod/hime
        /// <summary>
        /// Determines whether this instance has the required edge
        /// </summary>
        /// <param name="generation">The generation of the edge's start node</param>
        /// <param name="from">The edge's start node</param>
        /// <param name="to">The edge's target node</param>
        /// <returns><c>true</c> if this instance has the required edge; otherwise, <c>false</c></returns>
        public bool HasEdge(int generation, int from, int to)
        {
            GSSGeneration data = edgeGenerations[generation];

            for (int i = data.Start; i != data.Start + data.Count; i++)
            {
                GSSEdge edge = edges[i];
                if (edge.From == from && edge.To == to)
                {
                    return(true);
                }
            }
            return(false);
        }
示例#8
0
        /// <summary>
        /// Raises an error on an unexepcted token
        /// </summary>
        /// <param name="stem">The size of the generation's stem</param>
        private void OnUnexpectedToken(int stem)
        {
            // build the list of expected terminals
            List <Symbol> expected = new List <Symbol>();
            GSSGeneration genData  = gss.GetGeneration();

            for (int i = 0; i != genData.Count; i++)
            {
                LRExpected expectedOnHead = parserAutomaton.GetExpected(gss.GetRepresentedState(i + genData.Start), lexer.Terminals);
                // register the terminals for shift actions
                foreach (Symbol terminal in expectedOnHead.Shifts)
                {
                    if (!expected.Contains(terminal))
                    {
                        expected.Add(terminal);
                    }
                }
                if (i < stem)
                {
                    // the state was in the stem, also look for reductions
                    foreach (Symbol terminal in expectedOnHead.Reductions)
                    {
                        if (!expected.Contains(terminal) && CheckIsExpected(i + genData.Start, terminal))
                        {
                            expected.Add(terminal);
                        }
                    }
                }
            }
            // register the error
            UnexpectedTokenError error = new UnexpectedTokenError(lexer.tokens[nextToken.Index], new ROList <Symbol>(expected));

            allErrors.Add(error);
#if !NETSTANDARD1_0
            if (ModeDebug)
            {
                Console.WriteLine("==== RNGLR parsing error:");
                Console.Write("\t");
                Console.WriteLine(error);
                TextContext context = lexer.Input.GetContext(error.Position);
                Console.Write("\t");
                Console.WriteLine(context.Content);
                Console.Write("\t");
                Console.WriteLine(context.Pointer);
                gss.Print();
            }
#endif
        }
示例#9
0
文件: GSS.cs 项目: sebgod/hime
        /// <summary>
        /// Gets all paths in the GSS starting at the given node and with the given length
        /// </summary>
        /// <param name="from">The starting node</param>
        /// <param name="length">The length of the requested paths</param>
        /// <param name="count">The number of paths</param>
        /// <returns>A collection of paths in this GSS</returns>
        public GSSPath[] GetPaths(int from, int length, out int count)
        {
            if (length == 0)
            {
                // use the common 0-length GSS path to avoid new memory allocation
                path0.Last = from;
                count      = 1;
                return(paths0);
            }

            // Initializes the first path
            SetupPath(0, from, length);

            // The number of paths in the list
            int total = 1;

            // For the remaining hops
            for (int i = 0; i != length; i++)
            {
                int m    = 0;                       // Insertion index for the compaction process
                int next = total;                   // Insertion index for new paths
                for (int p = 0; p != total; p++)
                {
                    int last     = paths[p].Last;
                    int genIndex = paths[p].Generation;
                    // Look for new additional paths from last
                    GSSGeneration gen             = edgeGenerations[genIndex];
                    int           firstEdgeTarget = -1;
                    int           firstEdgeLabel  = -1;
                    for (int e = gen.Start; e != gen.Start + gen.Count; e++)
                    {
                        GSSEdge edge = edges[e];
                        if (edge.From == last)
                        {
                            if (firstEdgeTarget == -1)
                            {
                                // This is the first edge
                                firstEdgeTarget = edge.To;
                                firstEdgeLabel  = edge.Label;
                            }
                            else
                            {
                                // Not the first edge
                                // Clone and extend the new path
                                SetupPath(next, edge.To, length);
                                paths[next].CopyLabelsFrom(paths[p], i);
                                paths[next][i] = edge.Label;
                                // Go to next insert
                                next++;
                            }
                        }
                    }
                    // Check whether there was at least one edge
                    if (firstEdgeTarget != -1)
                    {
                        // Continue the current path
                        if (m != p)
                        {
                            GSSPath t = paths[m];
                            paths[m] = paths[p];
                            paths[p] = t;
                        }
                        paths[m].Last       = firstEdgeTarget;
                        paths[m].Generation = GetGenerationOf(firstEdgeTarget);
                        paths[m][i]         = firstEdgeLabel;
                        // goto next
                        m++;
                    }
                }
                if (m != total)
                {
                    // if some previous paths have been removed
                    // => compact the list if needed
                    for (int p = total; p != next; p++)
                    {
                        GSSPath t = paths[m];
                        paths[m] = paths[p];
                        paths[p] = t;
                        m++;
                    }
                    // m is now the exact number of paths
                    total = m;
                }
                else if (next != total)
                {
                    // no path has been removed, but some have been added
                    // => next is the exact number of paths
                    total = next;
                }
            }

            count = total;
            return(paths);
        }