Esempio n. 1
0
 protected override T DefaultProduction(
     string capturedValue,
     Stack <ParseTree.Node> operandStack,
     ProductionObjects productions)
 {
     throw new ParseErrorException();
 }
Esempio n. 2
0
 protected virtual T DefaultProduction(
     string capturedValue,
     Stack <ParseTree.Node> operandStack,
     ProductionObjects productions)
 {
     return(CreateInstance());
 }
Esempio n. 3
0
 protected virtual bool TestPreCondition(
     ParseTree.Node node,
     string capturedValue,
     Stack <ParseTree.Node> operandStack,
     ProductionObjects productions)
 {
     if (PreCondition == null)
     {
         return(true);
     }
     return(PreCondition(node));
 }
Esempio n. 4
0
            IEnumerable <ActionSchedule> ScheduleActions(ProductionObjects childProductions)
            {
                // actions with order of definition
                var actionsOrder = Actions
                                   .Select((a, aIdx) => new
                {
                    Self  = a,
                    Index = aIdx,
                    a.SourceTokenId
                });
                var dependentActions = actionsOrder
                                       .Where(a => !string.IsNullOrEmpty(a.SourceTokenId));
                var independentActions = actionsOrder
                                         .Where(a => string.IsNullOrEmpty(a.SourceTokenId));

                // child productions with order of creation
                var productionsOrder = childProductions
                                       .Select((p, pIdx) => new
                {
                    Self    = p.Value,
                    Index   = pIdx,
                    TokenId = p.Key
                });

                // schedule actions that depend on child production:
                //  * actions x productions
                //  * sorted by production creation order (inverted)
                //  * and then by action definition order (inverted)
                var dependentActionSchedules = dependentActions
                                               .Join(productionsOrder,
                                                     a => a.SourceTokenId, p => p.TokenId,
                                                     (a, p) => new ActionSchedule
                {
                    Action          = a.Self,
                    ActionIndex     = a.Index,
                    Production      = p.Self,
                    ProductionIndex = p.Index,
                })
                                               .OrderByDescending(ap => ap.ProductionIndex)
                                               .ThenByDescending(ap => ap.ActionIndex);

                // insert independent actions in the right order
                var scheduled = new Stack <ActionSchedule>();
                IEnumerable <ActionSchedule> toSchedule = dependentActionSchedules;

                foreach (var a in independentActions.OrderByDescending(a => a.Index))
                {
                    var scheduleAfter = toSchedule
                                        .TakeWhile(ap => ap.ActionIndex > a.Index);
                    foreach (var ap in scheduleAfter)
                    {
                        scheduled.Push(ap);
                    }
                    scheduled.Push(new ActionSchedule {
                        Action = a.Self
                    });

                    toSchedule = toSchedule.Skip(scheduleAfter.Count());
                }
                if (toSchedule.Any())
                {
                    foreach (var ap in toSchedule)
                    {
                        scheduled.Push(ap);
                    }
                }

                return(scheduled);
            }
Esempio n. 5
0
            ////////////////////////////////////////////////////////////////////////////////////////
            ///
            /// RegExpr.Parser.GetProductionObjects()
            ///
            ////////////////////////////////////////////////////////////////////////////////////////
            /// <summary>
            /// Extract productions from a parse tree.
            /// </summary>
            /// <param name="root">
            /// Root node of parse tree, obtained from parsing an input text with a RegExpr
            /// </param>
            /// <returns>Productions by token id</returns>
            ProductionObjects GetProductionObjects(ParseTree parseTree)
            {
                var outputProductions = new ProductionObjects();

                var stack = new Stack <ParseTree.Node>();

                stack.Push(parseTree.Root);
                while (stack.Any())
                {
                    var node = stack.Pop();

                    // Depth-first traversal
                    if (node.TokenStream == null)
                    {
                        node.TokenStream   = new Queue <ParseTree.Node>(node.ChildNodes.Values);
                        node.OperandStack  = new Stack <ParseTree.Node>();
                        node.OperatorStack = new Stack <ParseTree.Node>();
                        stack.Push(node);
                        continue;
                    }
                    else if (node.TokenStream.Any())
                    {
                        var nextNode = node.TokenStream.Dequeue();
                        stack.Push(node);
                        stack.Push(nextNode);
                        continue;
                    }

                    if (node.Parent == null)
                    {
                        continue;
                    }

                    var operatorStack = node.Parent.OperatorStack;
                    var operandStack  = node.Parent.OperandStack;
                    var rule          = node.Rule;
                    if (rule == null)
                    {
                        // Default token (without rule definitions)
                        // just use captured value as production
                        node.Production = node.Value;
                        operandStack.Push(node);
                    }
                    else if (rule.Delimiters != Delimiter.None)
                    {
                        // Delimiter token
                        if (rule.Delimiters == Delimiter.Left)
                        {
                            // if left delim, push to operator stack
                            operatorStack.Push(node);
                        }
                        else
                        {
                            // if right delim, unwind operator stack until left delim
                            UnwindOperatorStack(HaltUnwind.AtLeftDelimiter,
                                                operatorStack, operandStack);
                            // set left delim as left operand, delimited expr as right operand
                            operandStack.ReverseTop();
                            // execute delimiter rule
                            node.Production = rule.Execute(node);
                            operandStack.Push(node);
                        }
                    }
                    else if (rule.Operands != Operand.None)
                    {
                        // Operator token
                        // unwind operator stack until lower priority operator or empty
                        UnwindOperatorStack(HaltUnwind.AtLowerPriority,
                                            operatorStack, operandStack, rule.Priority);

                        // if operator needs left operand but none is available, error out
                        if (rule.Operands.HasFlag(Operand.Left) && !operandStack.Any())
                        {
                            throw new ParseErrorException();
                        }

                        if (rule.Operands.HasFlag(Operand.Right))
                        {
                            // if needs right operand, push to operator stack
                            operatorStack.Push(node);
                        }
                        else
                        {
                            // if left operand only, execute rule immediately
                            node.Production = rule.Execute(node);
                            operandStack.Push(node);
                        }
                    }
                    else
                    {
                        // Captured value or embedded captures ("nullary operator")
                        // execute rule immediately
                        node.Production = rule.Execute(node);
                        operandStack.Push(node);
                    }

                    if (node.IsLast)
                    {
                        // Last token
                        // unwind operator stack until empty
                        UnwindOperatorStack(HaltUnwind.WhenEmpty,
                                            operatorStack, operandStack);

                        // get output from operand stack
                        foreach (var operand in operandStack.Reverse())
                        {
                            // check if it's a dangling left delimiter
                            if (operand.Rule != null && operand.Rule.Delimiters == Delimiter.Left)
                            {
                                throw new ParseErrorException();
                            }

                            // add production to parent context
                            node.Parent.ChildProductions.Add(operand.TokenId, operand.Production);

                            // add production to output list
                            outputProductions.Add(operand.TokenId, operand.Production);
                        }
                        operandStack.Clear();
                    }
                }

                return(outputProductions);
            }