示例#1
0
    public ShiftParserAction(BnfTerm term, ParserState newState) {
      if (newState == null)
        throw new Exception("ParserShiftAction: newState may not be null. term: " + term.ToString());

      Term = term; 
      NewState = newState;
    }
 public PrecedenceBasedParserAction(BnfTerm shiftTerm, ParserState newShiftState, Production reduceProduction)
 {
     _reduceAction = new ReduceParserAction(reduceProduction);
     var reduceEntry = new ConditionalEntry(CheckMustReduce, _reduceAction, "(Precedence comparison)");
     ConditionalEntries.Add(reduceEntry);
     DefaultAction = _shiftAction = new ShiftParserAction(shiftTerm, newShiftState);
 }
示例#3
0
 public AstNodeArgs(BnfTerm term, CompilerContext context, SourceSpan span, AstNodeList childNodes)
 {
     Context = context;
       Term = term;
       Span = span;
       ChildNodes = childNodes;
 }
示例#4
0
    private void CollectTermsRecursive(BnfTerm term) {
      if (_grammarData.AllTerms.Contains(term)) return;
      _grammarData.AllTerms.Add(term);
      NonTerminal nt = term as NonTerminal;
      if (nt == null) return;

      if (string.IsNullOrEmpty(nt.Name)) {
        if (nt.Rule != null && !string.IsNullOrEmpty(nt.Rule.Name))
          nt.Name = nt.Rule.Name;
        else
          nt.Name = "Unnamed" + (_unnamedCount++);
      }
      if (nt.Rule == null)
        _language.Errors.AddAndThrow(GrammarErrorLevel.Error, null, Resources.ErrNtRuleIsNull, nt.Name);
      //check all child elements
      foreach (BnfTermList elemList in nt.Rule.Data)
        for (int i = 0; i < elemList.Count; i++) {
          BnfTerm child = elemList[i];
          if (child == null) {
            _language.Errors.Add(GrammarErrorLevel.Error, null, Resources.ErrRuleContainsNull, nt.Name, i);
            continue; //for i loop 
          }
          //Check for nested expression - convert to non-terminal
          BnfExpression expr = child as BnfExpression;
          if (expr != null) {
            child = new NonTerminal(null, expr);
            elemList[i] = child;
          }
          CollectTermsRecursive(child);
        }//for i
    }//method
示例#5
0
        public UnparsableAst(BnfTerm bnfTerm, object astValue, Member astParentMember = null)
        {
            this.BnfTerm = bnfTerm;
            this.AstValue = astValue;
            this.AstParentMember = astParentMember;

            this.IsLeftSiblingNeededForDeferredCalculation = false;
        }
 protected virtual Type GetDefaultNodeType(BnfTerm term)
 {
     if (term is NumberLiteral || term is StringLiteral)
         return Context.DefaultLiteralNodeType;
     if (term is IdentifierTerminal)
         return Context.DefaultIdentifierNodeType;
     return Context.DefaultNodeType;
 }
示例#7
0
        static void VerifyTerm(ParseTreeNode parseTreeNode, BnfTerm expectedTerm, params BnfTerm[] moreExpectedTerms)
        {
            var allExpected = new[] { expectedTerm }.Concat(moreExpectedTerms);

            if (!allExpected.Where(node => parseTreeNode.Term == node).Any())
            {
                throw new InvalidOperationException("expected '{0}' to be a '{1}'".FormatString(parseTreeNode, allExpected.JoinString(", ")));
            }
        }
示例#8
0
        internal static ExpressionUnparser.BnfTermKind DebugWriteLineBnfTermKind(this ExpressionUnparser.BnfTermKind bnfTermKind, TraceSource ts, BnfTerm bnfTerm, string extraMessage = null)
        {
            ts.Debug(
                "{0}, kind: {1}{2}",
                bnfTerm,
                bnfTermKind,
                extraMessage != null ? extraMessage : string.Empty
                );

            return bnfTermKind;
        }
示例#9
0
 private void Process(BnfTerm term, ParseTreeNode node)
 {
     if (node.Term == term)
     {
         Visit(node);
         return;
     }
     foreach (var childNode in node.ChildNodes)
     {
         Process(term, childNode);
     }
 }
示例#10
0
        private NonTerminal OrderBy(BnfTerm expression)
        {
            var orderingExpression = NonTerminal("orderByColumn",
                                                 expression + NonTerminal("orderingDirection", Empty | "ASC" | "DESC" | "УБЫВ" | "ВОЗР"),
                                                 ToOrderingElement);
            var orderColumnList = NonTerminal("orderColumnList", null);

            orderColumnList.Rule = MakePlusRule(orderColumnList, ToTerm(","), orderingExpression);
            return(NonTerminal("orderClauseOpt",
                               Empty | Transient("order", ToTerm("ORDER") | "УПОРЯДОЧИТЬ") + by + orderColumnList,
                               ToOrderByClause));
        }
示例#11
0
        private void CollectTermsRecursive(BnfTerm term)
        {
            if (_grammarData.AllTerms.Contains(term))
            {
                return;
            }
            _grammarData.AllTerms.Add(term);
            NonTerminal nt = term as NonTerminal;

            if (nt == null)
            {
                return;
            }

            if (string.IsNullOrEmpty(nt.Name))
            {
                if (nt.Rule != null && !string.IsNullOrEmpty(nt.Rule.Name))
                {
                    nt.Name = nt.Rule.Name;
                }
                else
                {
                    nt.Name = "Unnamed" + (_unnamedCount++);
                }
                nt.SetFlag(TermFlags.NoAstNode | TermFlags.IsTransient);
            }
            if (nt.Rule == null)
            {
                _language.Errors.AddAndThrow(GrammarErrorLevel.Error, null, Resources.ErrNtRuleIsNull, nt.Name);
            }
            //check all child elements
            foreach (BnfTermList elemList in nt.Rule.Data)
            {
                for (int i = 0; i < elemList.Count; i++)
                {
                    BnfTerm child = elemList[i];
                    if (child == null)
                    {
                        _language.Errors.Add(GrammarErrorLevel.Error, null, Resources.ErrRuleContainsNull, nt.Name, i);
                        continue; //for i loop
                    }
                    //Check for nested expression - convert to non-terminal
                    BnfExpression expr = child as BnfExpression;
                    if (expr != null)
                    {
                        child       = new NonTerminal(null, expr);
                        elemList[i] = child;
                    }
                    CollectTermsRecursive(child);
                } //for i
            }
        }         //method
示例#12
0
        /// <summary>
        /// Gets the child elements <see cref="ParseTreeNode"/> with the specified <see cref="BnfTerm"/>.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="term"></param>
        /// <returns></returns>
        public static IEnumerable <ParseTreeNode> Nodes(this ParseTreeNode node, BnfTerm term)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }
            if (term == null)
            {
                throw new ArgumentNullException(nameof(term));
            }

            return(node.ChildNodes.Where(i => i.Term == term));
        }
        public LRItemSet SelectByReducedLookahead(BnfTerm lookahead)
        {
            var result = new LRItemSet();

            foreach (var item in this)
            {
                if (item.ReducedLookaheads.Contains(lookahead))
                {
                    result.Add(item);
                }
            }
            return(result);
        }
示例#14
0
        private bool NeedParentheses(BnfTerm flaggedOperator)
        {
            BnfTerm leftFlaggedOperator  = GetLeftFlaggedSurroundingOperator();
            BnfTerm rightFlaggedOperator = GetRightFlaggedSurroundingOperator();

            return(leftFlaggedOperator != null &&
                   ((GetPrecedence(leftFlaggedOperator) > GetPrecedence(flaggedOperator) ||
                     GetPrecedence(leftFlaggedOperator) == GetPrecedence(flaggedOperator) && GetAssociativity(flaggedOperator) == Associativity.Left))
                   ||
                   rightFlaggedOperator != null &&
                   ((GetPrecedence(rightFlaggedOperator) > GetPrecedence(flaggedOperator) ||
                     GetPrecedence(rightFlaggedOperator) == GetPrecedence(flaggedOperator) && GetAssociativity(flaggedOperator) == Associativity.Right)));
        }
示例#15
0
        /// <summary>
        /// Gets the first child <see cref="ParseTreeNode"/> with the specfied <see cref="BnfTerm"/>.
        /// </summary>
        /// <param name="parseTree"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static ParseTreeNode Node(this ParseTree parseTree, BnfTerm term)
        {
            if (parseTree == null)
            {
                throw new ArgumentNullException(nameof(parseTree));
            }
            if (term == null)
            {
                throw new ArgumentNullException(nameof(term));
            }

            return(parseTree.Root.Term == term ? parseTree.Root : null);
        }
示例#16
0
        public LRItemSet SelectByCurrent(BnfTerm current)
        {
            var result = new LRItemSet();

            foreach (var item in this)
            {
                if (item.Core.Current == current)
                {
                    result.Add(item);
                }
            }
            return(result);
        }
示例#17
0
        /// <summary>
        /// Gets the first child <see cref="ParseTreeNode"/> with the specified <see cref="BnfTerm"/>.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static ParseTreeNode Node(this ParseTreeNode node, BnfTerm term)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }
            if (term == null)
            {
                throw new ArgumentNullException(nameof(term));
            }

            return(node.ChildNodes.Find(i => i.Term == term));
        }
示例#18
0
        private static string GetName(Type domainType, BnfTerm bnfTerm)
        {
            string name = string.Empty;

            if (bnfTerm != null)
            {
                name += bnfTerm.Name + "_";
            }

            name += "copyAs_" + domainType.Name.ToLower();

            return(name);
        }
        //Creates closure items with "spontaneously generated" lookaheads
        private bool AddClosureItems(ParserState state)
        {
            bool result = false;

            //note that we change collection while we iterate thru it, so we have to use "for i" loop
            for (int i = 0; i < state.Items.Count; i++)
            {
                LRItem  item     = state.Items[i];
                BnfTerm currTerm = item.Core.Current;
                if (currTerm == null || !(currTerm is NonTerminal))
                {
                    continue;
                }
                //1. Add normal closure items
                NtData currInfo = (NtData)currTerm.ParserData;
                foreach (Production prod in currInfo.Productions)
                {
                    LR0Item core    = prod.LR0Items[0]; //item at zero index is the one that starts with dot
                    LRItem  newItem = TryFindItem(state, core);
                    if (newItem == null)
                    {
                        newItem = new LRItem(state, core);
                        state.Items.Add(newItem);
                        result = true;
                    }
                    #region Comments on lookaheads processing
                    // The general idea of generating ("spontaneously") the lookaheads is the following:
                    // Let's the original item be in the form
                    //   [A -> alpha . B beta , lset]
                    //     where <B> is a non-terminal and <lset> is a set of lookaheads,
                    //      <beta> is some string (B's tail in our terminology)
                    // Then the closure item on non-teminal B is an item
                    //   [B -> x, firsts(beta + lset)]
                    //      (the lookahead set is expression after the comma).
                    // To generate lookaheads on a closure item, we simply take "firsts"
                    //   from the tail <beta> of the NonTerminal <B>.
                    //   Normally if tail <beta> is nullable we would add ("propagate")
                    //   the <lset> lookaheads from <A> to <B>.
                    //   We dont' do it right here - we simply add a propagation link.
                    //   We propagate all lookaheads later in a separate process.
                    #endregion
                    newItem.NewLookaheads.AddRange(item.Core.TailFirsts);
                    if (item.Core.TailIsNullable && !item.PropagateTargets.Contains(newItem))
                    {
                        item.PropagateTargets.Add(newItem);
                    }
                } //foreach prod
            }     //for i (LRItem)
            return(result);
        }
 public ShiftTransition(ParserState fromState, BnfTerm overTerm, LRItemSet shiftItems)
 {
     FromState  = fromState;
     OverTerm   = overTerm;
     ShiftItems = shiftItems;
     _hashCode  = unchecked (fromState.GetHashCode() - overTerm.GetHashCode());
     //Add self to state's set of transitions
     fromState.BuilderData.ShiftTransitions.Add(this);
     //Assign self to Transition field of all shift items
     foreach (var shiftItem in ShiftItems)
     {
         shiftItem.Transition = this;
     }
 }//constructor
示例#21
0
        private void RegisterMember(BnfTerm bnfTerm, IList <BnfTerm> rawEncloserBnfTerms, int rawEncloserBnfTermsIndex, int bnfTermIndexAtParse, int bnfTermIndexAtRule, Member member)
        {
            var encloserBnfTermsAtRule = rawEncloserBnfTerms
                                         .Where(_bnfTerm => !(_bnfTerm is GrammarHint))
                                         .Select(_bnfTerm => _bnfTerm is Member ? ((Member)_bnfTerm).BnfTerm : _bnfTerm)
                                         .ToList();

            var encloserBnfTermsAtParse = encloserBnfTermsAtRule
                                          .Where(encloserBnfTermAtRule => !encloserBnfTermAtRule.IsPunctuation())
                                          .ToList();

            this.referredBnfTermAtRuleToMember.Add(new ReferredBnfTermEI(rawEncloserBnfTermsIndex, bnfTerm, bnfTermIndexAtRule), member);
            this.referredBnfTermAtParseToMember.Add(new ReferredBnfTermEL(encloserBnfTermsAtParse, bnfTerm, bnfTermIndexAtParse), member);
        }
        }                     //method

        #endregion

        #region Calculating Tail Firsts
        private void CalculateTailFirsts()
        {
            foreach (NonTerminal nt in _grammar.NonTerminals)
            {
                foreach (Production prod in nt.Productions)
                {
                    StringSet accumulatedFirsts = new StringSet();
                    bool      allNullable       = true;
                    //We are going backwards in LR0Items list
                    for (int i = prod.LR0Items.Count - 1; i >= 0; i--)
                    {
                        LR0Item item = prod.LR0Items[i];
                        if (i >= prod.LR0Items.Count - 2)
                        {
                            //Last and before last items have empty tails
                            item.TailIsNullable = true;
                            item.TailFirsts.Clear();
                            continue;
                        }
                        BnfTerm nextTerm = prod.RValues[i + 1]; //Element after-after-dot; remember we're going in reverse direction
                        //if (ntElem == null) continue; //it is not NonTerminal
                        NonTerminal nextNt      = nextTerm as NonTerminal;
                        bool        notNullable = nextTerm is Terminal || nextNt != null && !nextNt.Nullable;
                        if (notNullable) //next term is not nullable  (a terminal or non-nullable NonTerminal)
                        //term is not nullable, so we clear all old firsts and add this term
                        {
                            accumulatedFirsts.Clear();
                            allNullable         = false;
                            item.TailIsNullable = false;
                            if (nextTerm is Terminal)
                            {
                                item.TailFirsts.Add(nextTerm.Key);//term is terminal so add its key
                                accumulatedFirsts.Add(nextTerm.Key);
                            }
                            else if (nextNt != null)                     //it is NonTerminal
                            {
                                item.TailFirsts.AddRange(nextNt.Firsts); //nonterminal
                                accumulatedFirsts.AddRange(nextNt.Firsts);
                            }
                            continue;
                        }
                        //if we are here, then ntElem is a nullable NonTerminal. We add
                        accumulatedFirsts.AddRange(nextNt.Firsts);
                        item.TailFirsts.AddRange(accumulatedFirsts);
                        item.TailIsNullable = allNullable;
                    } //for i
                }     //foreach prod
            }         //foreach nt
        }             //method
示例#23
0
文件: AstBuilder.cs 项目: DevMk/Irony
 // AST node type is not specified for term {0}. Either assign Term.AstConfig.NodeType, or specify default type(s) in AstBuilder.
 protected virtual Type GetDefaultNodeType(BnfTerm term)
 {
     if (term is NumberLiteral || term is StringLiteral)
     {
         return(Context.DefaultLiteralNodeType);
     }
     else if (term is IdentifierTerminal)
     {
         return(Context.DefaultIdentifierNodeType);
     }
     else
     {
         return(Context.DefaultNodeType);
     }
 }
示例#24
0
        protected void SetState(BnfiTermConversion source)
        {
            this.bnfTerm         = source.bnfTerm;
            this.value           = source.value;
            this.defaultValue    = source.defaultValue;
            this.isOptionalValue = source.isOptionalValue;
            this.Flags           = source.Flags;
            this.AstConfig       = source.AstConfig;

            this.inverseValueConverterForUnparse = source.inverseValueConverterForUnparse;

            if (this.UtokenizerForUnparse != null)
            {
                this.UtokenizerForUnparse = source.UtokenizerForUnparse;
            }
        }
示例#25
0
        protected BnfiTermCopy(Type domainType, BnfTerm bnfTerm, string name)
            : base(domainType, name: name ?? GetName(domainType, bnfTerm))
        {
            if (bnfTerm != null)
            {
                // "this" BnfiTermCopy is not an independent bnfTerm, just a syntax magic for BnfiTermRecord<TType> (we were called by the Copy method)
                this.IsContractible = true;
                this.RuleRaw        = bnfTerm.ToBnfExpression() + GrammarHelper.ReduceHere();
            }
            else
            {
                // "this" BnfiTermCopy is an independent bnfTerm
                this.IsContractible = false;
            }

            GrammarHelper.MarkTransientForced(this);    // default "transient" behavior (the Rule of this BnfiTermCopyable will contain the BnfiTerm... which actually does something)
        }
示例#26
0
        private object ConvertAstValueForChild(object astValue, BnfTerm childBnfTerm)
        {
            /*
             * If UtokenizerForUnparse is not null then this method is being called only for child priority calculations, and not for
             * actually getting the children for unparse. However, if we are being called for priority calculations, we shouldn't
             * throw an exception because of the unimplemented inverseValueConverterForUnparse.
             * */

            if (IsMainChild(childBnfTerm) && UtokenizerForUnparse == null)
            {
                return(this.inverseValueConverterForUnparse(astValue));
            }
            else
            {
                return(astValue);
            }
        }
示例#27
0
        }//method

        private int GetLookaheadOccurenceCount(ParserState state, BnfTerm lookahead)
        {
            var result = 0;

            foreach (var reduceItem in state.BuilderData.ReduceItems)
            {
                if (reduceItem.AllLookaheads.Contains(lookahead))
                {
                    result++;
                }
            }
            //add 1 if it is shift term
            if (state.BuilderData.ShiftTerms.Contains(lookahead))
            {
                result++;
            }
            return(result);
        }
示例#28
0
        private BnfTermKind CalculateBnfTermKind(BnfTerm current)
        {
            BnfTermKind currentKind;

            if (this.bnfTermToBnfTermKind.TryGetValue(current, out currentKind))
            {
                /*
                 * if currentKind is Undetermined here it means that we are in a recursion,
                 * which means that currentKind can be only Other (i.e. not an operator, nor a parenthesis, etc.)
                 * */
                if (currentKind == BnfTermKind.Undetermined)
                {
                    this.bnfTermToBnfTermKind[current] = currentKind = BnfTermKind.Other;
                }

                return(currentKind);
            }

            this.bnfTermToBnfTermKind.Add(current, BnfTermKind.Undetermined);

            tsParentheses.Indent();

            // need to "label" every bnfterm
            if (current is NonTerminal)
            {
                currentKind = CalculateBnfTermKindForNonTerminal((NonTerminal)current);
            }
            else
            {
                currentKind = BnfTermKind.Other;
            }

            // e.g. operator can be non-terminal and terminal as well (or at least they can be flagged so); if it is non-terminal, then we override currentKind
            OverrideBnfTermKindInCaseOfSpecificInfo(current, ref currentKind);

            tsParentheses.Unindent();
            currentKind.DebugWriteLineBnfTermKind(tsParentheses, current);

            Debug.Assert(currentKind != BnfTermKind.Undetermined);

            this.bnfTermToBnfTermKind[current] = currentKind;        // not using Add, because bnfTermToBnfTermKind[current] has already been set to Undetermined or Other

            return(currentKind);
        }
示例#29
0
        private NonTerminal AttributesList(BnfTerm identifier)
        {
            var options        = StringOptions.AllowsAllEscapes | StringOptions.AllowsLineBreak;
            var attributeValue = new StringLiteral("attributeValue", "'", options,
                                                   (context, node) => node.AstNode = node.Token.ValueString);

            attributeValue.AddStartEnd("\"", options);
            var attribute = NonTerminal("attribute", null, node => new Attribute
            {
                Name  = (CompositeIdentifier)node.ChildNodes[0].AstNode,
                Value = (string)node.ChildNodes[2].AstNode
            });
            var attributesList = NonTerminal("attributesList", null,
                                             node => node.ChildNodes.Select(c => (Attribute)c.AstNode).ToList());

            attribute.Rule      = identifier + "=" + attributeValue;
            attributesList.Rule = MakeStarRule(attributesList, attribute);
            return(attributesList);
        }
示例#30
0
        private NonTerminal Join(BnfTerm columnSource, BnfTerm joinCondition)
        {
            var joinKindOpt     = NonTerminal("joinKindOpt", null);
            var joinItem        = NonTerminal("joinItem", null, ToJoinClause);
            var joinItemList    = NonTerminal("joinItemList", null);
            var outerJoinKind   = NonTerminal("outerJoinKind", null, TermFlags.IsTransient);
            var outerKeywordOpt = NonTerminal("outerKeywordOpt", null, TermFlags.NoAstNode | TermFlags.IsPunctuation);
            var on = NonTerminal("on", ToTerm("ON") | "ПО", TermFlags.NoAstNode);

            outerKeywordOpt.Rule = ToTerm("OUTER") | "ВНЕШНЕЕ" | Empty;
            outerJoinKind.Rule   = ToTerm("FULL") | "LEFT" | "RIGHT" | "ПОЛНОЕ" | "ЛЕВОЕ" | "ПРАВОЕ";
            joinItem.Rule        = joinKindOpt + Transient("join", ToTerm("JOIN") | "СОЕДИНЕНИЕ") + columnSource + on +
                                   joinCondition;

            joinKindOpt.Rule = Empty | Transient("inner", ToTerm("INNER") | "ВНУТРЕННЕЕ") |
                               (outerJoinKind + outerKeywordOpt);
            joinItemList.Rule = MakeStarRule(joinItemList, null, joinItem);

            return(joinItemList);
        }
示例#31
0
        private void HandleOperators(BnfTerm @operator, IEnumerable <BnfTerm> childOperators)
        {
            BnfTerm strongestFlaggedChildOperator = childOperators.Aggregate(
                (BnfTerm)null,
                (strongestFlaggedChildOperatorSoFar, childOperator) => strongestFlaggedChildOperatorSoFar == null ||
                GetPrecedence(_flaggedOrDerivedOperatorToMultiOperatorInfo[childOperator].StrongestFlaggedOperator) > GetPrecedence(_flaggedOrDerivedOperatorToMultiOperatorInfo[strongestFlaggedChildOperatorSoFar].StrongestFlaggedOperator)
                    ? _flaggedOrDerivedOperatorToMultiOperatorInfo[childOperator].StrongestFlaggedOperator
                    : strongestFlaggedChildOperatorSoFar
                );

            BnfTerm weakestFlaggedChildOperator = childOperators.Aggregate(
                (BnfTerm)null,
                (weakestFlaggedChildOperatorSoFar, childOperator) => weakestFlaggedChildOperatorSoFar == null ||
                GetPrecedence(_flaggedOrDerivedOperatorToMultiOperatorInfo[childOperator].WeakestFlaggedOperator) > GetPrecedence(_flaggedOrDerivedOperatorToMultiOperatorInfo[weakestFlaggedChildOperatorSoFar].WeakestFlaggedOperator)
                    ? _flaggedOrDerivedOperatorToMultiOperatorInfo[childOperator].WeakestFlaggedOperator
                    : weakestFlaggedChildOperatorSoFar
                );

            _flaggedOrDerivedOperatorToMultiOperatorInfo.Add(@operator, new MultiOperatorInfo(strongestFlaggedChildOperator, weakestFlaggedChildOperator));
        }
示例#32
0
 private void OverrideBnfTermKindInCaseOfSpecificInfo(BnfTerm current, ref BnfTermKind currentKind)
 {
     if (IsFlaggedOperator(current))
     {
         currentKind = BnfTermKind.Operator;
         _flaggedOrDerivedOperatorToMultiOperatorInfo[current] = new MultiOperatorInfo(current, current);
     }
     else if (current.IsOpenBrace())
     {
         currentKind = BnfTermKind.LeftParenthesis;
     }
     else if (current.IsCloseBrace())
     {
         currentKind = BnfTermKind.RightParenthesis;
     }
     else if (current is GrammarHint)
     {
         currentKind = BnfTermKind.GrammarHint;
     }
 }
示例#33
0
        static void ProcessParseTreeNode(BnfTerm node)
        {
            var nt = node as NonTerminal;
            if (nt == null)
                return;
            if (node_names.ContainsKey (nt))
                return;
            string name = "AS" + ToPascalCase (nt.Name) + "AstNode";
            node_names.Add (nt, name);

            // process descendants
            foreach (var p in nt.Productions)
                foreach (var c in p.RValues)
                    ProcessParseTreeNode (c);

            foreach (var p in nt.Productions)
                Console.WriteLine ("\t// {0}", p.GetType ());
            Console.WriteLine ("\tpublic partial class {0} : ActionScriptAstNode", name);
            Console.WriteLine ("\t{");
            Console.Write ("\t\t// {0} productions: ", nt.Productions.Count);
            foreach (var p in nt.Productions)
                foreach (var c in p.RValues) {
                    Console.Write (ToPascalCase (c.Name));
                    Console.Write (' ');
                }
            Console.WriteLine ();
            if ((nt.Flags & TermFlags.IsList) != 0 && nt.Productions.Count > 0 && nt.Productions [0].RValues [0] == nt) {
                var cnt = nt.Productions [0].RValues.Last () as NonTerminal;
                if (cnt != null)
                    Console.WriteLine ("\t\tpublic {0} {1} {{ get; set; }}", node_names [cnt], ToPascalCase (cnt.Name));
            } else {
                foreach (var p in nt.Productions)
                    foreach (var c in p.RValues) {
                        var cnt = c as NonTerminal;
                        if (cnt == null)
                            continue;
                        Console.WriteLine ("\t\tpublic {0} {1} {{ get; set; }}", node_names [cnt], ToPascalCase (cnt.Name));
                    }
            }
            Console.WriteLine ("\t}");
        }
示例#34
0
        //Find an LR item without hints compatible with term (either shift on term or reduce with term as lookahead);
        // this item without hints would become our default. We assume that other items have hints, and when conditions
        // on all these hints fail, we chose this remaining item without hints.
        private static ParserAction FindDefaultAction(ParserState state, BnfTerm term)
        {
            //First check reduce items
            var reduceItems = state.BuilderData.ReduceItems.SelectByLookahead(term as Terminal);

            foreach (var item in reduceItems)
            {
                if (item.Core.Hints.Count == 0)
                {
                    return(ReduceParserAction.Create(item.Core.Production));
                }
            }
            var shiftItem = state.BuilderData.ShiftItems.SelectByCurrent(term).FirstOrDefault();

            if (shiftItem != null)
            {
                return(new ShiftParserAction(shiftItem));
            }
            //if everything failed, returned first reduce item
            return(null);
        }
        }//method

        private ShiftTable GetStateShifts(ParserState state)
        {
            ShiftTable  shifts = new ShiftTable();
            LR0ItemList list;

            foreach (LRItem item in state.Items)
            {
                BnfTerm term = item.Core.Current;
                if (term == null)
                {
                    continue;
                }
                LR0Item shiftedItem = item.Core.Production.LR0Items[item.Core.Position + 1];
                if (!shifts.TryGetValue(term.Key, out list))
                {
                    shifts[term.Key] = list = new LR0ItemList();
                }
                list.Add(shiftedItem);
            } //foreach
            return(shifts);
        }     //method
示例#36
0
        /// <summary>
        /// Gets the child elements <see cref="ParseTreeNode"/> with the specified <see cref="BnfTerm"/>.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static IEnumerable <ParseTreeNode> Nodes(this ParseTree parseTree, BnfTerm term)
        {
            if (parseTree == null)
            {
                throw new ArgumentNullException(nameof(parseTree));
            }
            if (parseTree.Root == null)
            {
                throw new ArgumentNullException(nameof(parseTree));
            }
            if (parseTree.Root.Term == null)
            {
                throw new ArgumentNullException(nameof(parseTree));
            }
            if (term == null)
            {
                throw new ArgumentNullException(nameof(term));
            }

            return(parseTree.Root.Term == term ? new[] { parseTree.Root } : Enumerable.Empty <ParseTreeNode>());
        }
示例#37
0
        protected BnfiTermConversion(Type domainType, BnfTerm bnfTerm, ValueIntroducer <object> valueIntroducer, ValueConverter <object, object> inverseValueConverterForUnparse,
                                     object defaultValue, bool isOptionalValue, string name, bool astForChild)
            : base(domainType, name)
        {
            this.IsContractible  = true;
            this.bnfTerm         = bnfTerm;
            this.isOptionalValue = isOptionalValue;
            this.defaultValue    = defaultValue;

            if (!astForChild)
            {
                bnfTerm.SetFlag(TermFlags.NoAstNode);
            }

            this.RuleRawWithMove = isOptionalValue
                ? GrammarHelper.PreferShiftHere() + bnfTerm | Irony.Parsing.Grammar.CurrentGrammar.Empty
                : bnfTerm.ToBnfExpression();

            this.AstConfig.NodeCreator =
                (context, parseTreeNode) =>
            {
                try
                {
                    parseTreeNode.AstNode = GrammarHelper.ValueToAstNode(valueIntroducer(context, new ParseTreeNodeWithoutAst(parseTreeNode)), context, parseTreeNode);
                }
                catch (AstException e)
                {
                    context.AddMessage(AstException.ErrorLevel, parseTreeNode.Span.Location, e.Message);
                }
                catch (FatalAstException e)
                {
                    context.AddMessage(FatalAstException.ErrorLevel, parseTreeNode.Span.Location, e.Message); // although it will be abandoned anyway
                    e.Location = parseTreeNode.Span.Location;
                    throw;                                                                                    // handle in MultiParser
                }
            };

            this.inverseValueConverterForUnparse = inverseValueConverterForUnparse;
        }
示例#38
0
        public static Automaton CreateAutomaton(Grammar g)
        {
            //initialise to closure of start item
            HashSet <ParseState> states = new HashSet <ParseState>();

            states.Add(g.Productions.Where(a => a.Head.Equals(g.Root)).Select(a => new Item(a, 0)).Closure(g));

            HashSet <ParseStateTransition> transitions = new HashSet <ParseStateTransition>();

            HashSet <ParseState>           sToAdd = new HashSet <ParseState>();
            HashSet <ParseStateTransition> tToAdd = new HashSet <ParseStateTransition>();

            do
            {
                sToAdd.Clear();
                tToAdd.Clear();

                foreach (var state in states)
                {
                    foreach (var item in state)
                    {
                        if (item.Production.Body.Length == item.Position)
                        {
                            continue;
                        }

                        BnfTerm    term = item.Production.Body[item.Position];
                        ParseState j    = state.Goto(term, g);

                        sToAdd.Add(j);
                        tToAdd.Add(new ParseStateTransition(state, term, j));
                    }
                }
            }while (states.UnionWithAddedCount(sToAdd) != 0 | transitions.UnionWithAddedCount(tToAdd) != 0);

            return(new Automaton(transitions, g));
        }
    private void CollectTermsRecursive(BnfTerm term) {
      // Do not add pseudo terminals defined as static singletons in Grammar class (Empty, Eof, etc)
      //  We will never see these terminals in the input stream.
      //   Filter them by type - their type is exactly "Terminal", not derived class. 
      if (term.GetType() == typeof(Terminal)) return;
      if (_grammarData.AllTerms.Contains(term)) return;
      _grammarData.AllTerms.Add(term);
      NonTerminal nt = term as NonTerminal;
      if (nt == null) return;

      if (nt.Name == null) {
        if (nt.Rule != null && !string.IsNullOrEmpty(nt.Rule.Name))
          nt.Name = nt.Rule.Name;
        else
          nt.Name = "NT" + (_unnamedCount++);
      }
      if (nt.Rule == null) {
        _language.Errors.Add("Non-terminal " + nt.Name + " has uninitialized Rule property.");
        return;
      }
      //check all child elements
      foreach (BnfTermList elemList in nt.Rule.Data)
        for (int i = 0; i < elemList.Count; i++) {
          BnfTerm child = elemList[i];
          if (child == null) {
            _language.Errors.Add("Rule for NonTerminal " + nt.Name + " contains null as an operand in position " + i.ToString() + " in one of productions.");
            continue; //for i loop 
          }
          //Check for nested expression - convert to non-terminal
          BnfExpression expr = child as BnfExpression;
          if (expr != null) {
            child = new NonTerminal(null, expr);
            elemList[i] = child;
          }
          CollectTermsRecursive(child);
        }//for i
    }//method
示例#40
0
        protected static IEnumerable <T> GetAllAstNodesOf <T>(ParseTreeNode node, BnfTerm term)
        {
            if (node.Term == term)
            {
                yield return((T)node.AstNode);
            }
            foreach (var n in node.ChildNodes)
            {
                if (n.Term == term)
                {
                    yield return((T)n.AstNode);
                }

                if (n.ChildNodes.Count == 0)
                {
                    continue;
                }

                foreach (var result in n.ChildNodes.SelectMany(nInner => GetAllAstNodesOf <T>(nInner, term)))
                {
                    yield return(result);
                }
            }
        }
示例#41
0
 private void ResolveConflictByHints(ParserState state, BnfTerm conflict)
 {
     if (TryResolveConflictByHints(state, conflict))
     state.BuilderData.ResolvedConflicts.Add(conflict);
 }
示例#42
0
 protected BnfExpression MakeListRule(NonTerminal list, BnfTerm delimiter, BnfTerm listMember, TermListOptions options = TermListOptions.PlusList)
 {
     //If it is a star-list (allows empty), then we first build plus-list
       var isPlusList = !options.IsSet(TermListOptions.AllowEmpty);
       var allowTrailingDelim = options.IsSet(TermListOptions.AllowTrailingDelimiter) && delimiter != null;
       //"plusList" is the list for which we will construct expression - it is either extra plus-list or original list.
       // In the former case (extra plus-list) we will use it later to construct expression for list
       NonTerminal plusList = isPlusList ? list : new NonTerminal(listMember.Name + "+");
       plusList.SetFlag(TermFlags.IsList);
       plusList.Rule = plusList;  // rule => list
       if (delimiter != null)
     plusList.Rule += delimiter;  // rule => list + delim
       if (options.IsSet(TermListOptions.AddPreferShiftHint))
     plusList.Rule += PreferShiftHere(); // rule => list + delim + PreferShiftHere()
       plusList.Rule += listMember;          // rule => list + delim + PreferShiftHere() + elem
       plusList.Rule |= listMember;        // rule => list + delim + PreferShiftHere() + elem | elem
       if (isPlusList) {
     // if we build plus list - we're almost done; plusList == list
     // add trailing delimiter if necessary; for star list we'll add it to final expression
     if (allowTrailingDelim)
       plusList.Rule |= list + delimiter; // rule => list + delim + PreferShiftHere() + elem | elem | list + delim
       } else {
     // Setup list.Rule using plus-list we just created
     list.Rule = Empty | plusList;
     if (allowTrailingDelim)
       list.Rule |= plusList + delimiter | delimiter;
     plusList.SetFlag(TermFlags.NoAstNode);
     list.SetFlag(TermFlags.IsListContainer); //indicates that real list is one level lower
       }
       return list.Rule;
 }
示例#43
0
 public BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember)
 {
     return MakeListRule(listNonTerminal, delimiter, listMember, TermListOptions.StarList);
 }
示例#44
0
 public BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember)
 {
     return MakeListRule(listNonTerminal, delimiter, listMember);
 }
示例#45
0
 public BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm listMember)
 {
     return MakeListRule(listNonTerminal, null, listMember);
 }
示例#46
0
 public BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember)
 {
     listNonTerminal.SetOption(TermOptions.IsList);
       if (delimiter == null)
     listNonTerminal.Rule = listMember | listNonTerminal + listMember;
       else
     listNonTerminal.Rule = listMember | listNonTerminal + delimiter + listMember;
       return listNonTerminal.Rule;
 }
示例#47
0
 private ValueReader uniOpCreate(BnfTerm op, ValueReader value)
 {
     if (grammar.Not == op) return new NotOpReader(value);
     if (grammar.Minus == op) return new NegOpReader(value);
     Game.CurrentGame.Die("Error with implementation of operator " + op.Name);
     return null;
 }
示例#48
0
 public static BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember, TermListOptions options) {
    bool allowTrailingDelimiter = (options & TermListOptions.AllowTrailingDelimiter) != 0;
   if (delimiter == null) {
     //it is much simpler case
     listNonTerminal.SetFlag(TermFlags.IsList);
     listNonTerminal.Rule = _currentGrammar.Empty | listNonTerminal + listMember;
     return listNonTerminal.Rule;
   }
   //Note that deceptively simple version of the star-rule 
   //       Elem* -> Empty | Elem | Elem* + delim + Elem
   //  does not work when you have delimiters. This simple version allows lists starting with delimiters -
   // which is wrong. The correct formula is to first define "Elem+"-list, and then define "Elem*" list 
   // as "Elem* -> Empty|Elem+" 
   NonTerminal plusList = new NonTerminal(listMember.Name + "+");
   plusList.Rule = MakePlusRule(plusList, delimiter, listMember);
   plusList.SetFlag(TermFlags.NoAstNode); //to allow it to have AstNodeType not assigned
   if (allowTrailingDelimiter)
     listNonTerminal.Rule = _currentGrammar.Empty | plusList | plusList + delimiter;
   else 
     listNonTerminal.Rule = _currentGrammar.Empty | plusList;
   listNonTerminal.SetFlag(TermFlags.IsListContainer); 
   return listNonTerminal.Rule;
 }
示例#49
0
 public static BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm listMember) {
   return MakeStarRule(listNonTerminal, null, listMember, TermListOptions.None);
 }
示例#50
0
 public static BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember) {
   if (delimiter == null)
     listNonTerminal.Rule = listMember | listNonTerminal + listMember;
   else 
     listNonTerminal.Rule = listMember | listNonTerminal + delimiter + listMember;
   listNonTerminal.SetFlag(TermFlags.IsList);
   return listNonTerminal.Rule;
 }
示例#51
0
 public static BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember, TermListOptions options) {
    bool allowTrailingDelimiter = (options & TermListOptions.AllowTrailingDelimiter) != 0;
   if (delimiter == null || !allowTrailingDelimiter)
     return MakePlusRule(listNonTerminal, delimiter, listMember); 
   //create plus list
   var plusList = new NonTerminal(listMember.Name + "+"); 
   plusList.Rule = MakePlusRule(listNonTerminal, delimiter, listMember);
   listNonTerminal.Rule = plusList | plusList + delimiter; 
   listNonTerminal.SetFlag(TermFlags.IsListContainer); 
   return listNonTerminal.Rule; 
 }
示例#52
0
 public BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember)
 {
     if (delimiter == null) {
     //it is much simpler case
     listNonTerminal.SetOption(TermOptions.IsList);
     listNonTerminal.Rule = Empty | listNonTerminal + listMember;
     return listNonTerminal.Rule;
       }
       NonTerminal tmp = new NonTerminal(listMember.Name + "+");
       MakePlusRule(tmp, delimiter, listMember);
       listNonTerminal.Rule = Empty | tmp;
       listNonTerminal.SetOption(TermOptions.IsStarList);
       return listNonTerminal.Rule;
 }
    }//method

    private int GetLookaheadOccurenceCount(ParserState state, BnfTerm lookahead) {
      var result = 0;
      foreach (var reduceItem in state.BuilderData.ReduceItems)
        if (reduceItem.AllLookaheads.Contains(lookahead))
          result++;
      //add 1 if it is shift term
      if (state.BuilderData.ShiftTerms.Contains(lookahead))
        result++;
      return result; 
    }
示例#54
0
 public static BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember) {
   if (delimiter == null) {
     //it is much simpler case
     listNonTerminal.SetOption(TermOptions.IsList);
     listNonTerminal.Rule = _currentGrammar.Empty | listNonTerminal + listMember;
     return listNonTerminal.Rule;
   }
   //Note that deceptively simple version of the star-rule 
   //       Elem* -> Empty | Elem | Elem* + delim + Elem
   //  does not work when you have delimiters. This simple version allows lists starting with delimiters -
   // which is wrong. The correct formula is to first define "Elem+"-list, and then define "Elem*" list 
   // as "Elem* -> Empty|Elem+" 
   NonTerminal tmp = new NonTerminal(listMember.Name + "+");
   tmp.SetOption(TermOptions.IsTransient); //important - mark it as Transient so it will be eliminated from AST tree
   MakePlusRule(tmp, delimiter, listMember);
   listNonTerminal.Rule = _currentGrammar.Empty | tmp;
   //listNonTerminal.SetOption(TermOptions.IsStarList);
   return listNonTerminal.Rule;
 }
示例#55
0
        private bool TryResolveConflictByHints(ParserState state, BnfTerm conflict)
        {
            var stateData = state.BuilderData;
              //reduce hints
              var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict);
              foreach(var reduceItem in reduceItems)
            if (reduceItem.Core.Hints != null)
              foreach (var hint in reduceItem.Core.Hints)
            if (hint.HintType == HintType.ResolveToReduce) {
              var newAction = ParserAction.CreateReduce(reduceItem.Core.Production);
              state.Actions[conflict] = newAction; //replace/add reduce action
              return true;
            }

              //Shift hints
              var shiftItems = stateData.ShiftItems.SelectByCurrent(conflict);
              foreach (var shiftItem in shiftItems)
            if (shiftItem.Core.Hints != null)
              foreach (var hint in shiftItem.Core.Hints)
            if (hint.HintType == HintType.ResolveToShift) {
              //shift action is already there
              return true;
            }

              //code hints
              // first prepare data for conflict action: reduceProduction (for possible reduce) and newState (for possible shift)
              var reduceProduction = reduceItems.First().Core.Production; //take first of reduce productions
              ParserState newState = (state.Actions.ContainsKey(conflict) ? state.Actions[conflict].NewState : null);
              // Get all items that might contain hints; first take all shift items and reduce items in conflict;
              // we should also add lookahead sources of reduce items. Lookahead source is an LR item that produces the lookahead,
              // so if it contains a code hint right before the lookahead term, then it applies to this conflict as well.
              var allItems = new LRItemList();
              allItems.AddRange(shiftItems);
              foreach (var reduceItem in reduceItems) {
            allItems.Add(reduceItem);
            allItems.AddRange(reduceItem.ReducedLookaheadSources);
              }
              // Scan all items and try to find hint with resolution type Code
              foreach (var item in allItems)
            if (item.Core.Hints != null)
              foreach (var hint in item.Core.Hints)
            if (hint.HintType == HintType.ResolveInCode) {
              //found hint with resolution type "code" - this is instruction to use custom code here to resolve the conflict
              // create new ConflictAction and place it into Actions table
              var newAction = ParserAction.CreateCodeAction(newState, reduceProduction);
              state.Actions[conflict] = newAction; //replace/add reduce action
              return true;
            }
              return false;
        }
示例#56
0
 protected BnfExpression MakeListRule(NonTerminal list, BnfTerm delimiter, BnfTerm listMember, TermListOptions options = TermListOptions.PlusList)
 {
     //If it is a star-list (allows empty), then we first build plus-list
       var isStarList = options.IsSet(TermListOptions.AllowEmpty);
       NonTerminal plusList = isStarList ? new NonTerminal(listMember.Name + "+") : list;
       //"list" is the real list for which we will construct expression - it is either extra plus-list or original listNonTerminal.
       // In the latter case we will use it later to construct expression for listNonTerminal
       plusList.Rule = plusList;  // rule => list
       if (delimiter != null)
     plusList.Rule += delimiter;  // rule => list + delim
       if (options.IsSet(TermListOptions.AddPreferShiftHint))
     plusList.Rule += PreferShiftHere(); // rule => list + delim + PreferShiftHere()
       plusList.Rule += listMember;          // rule => list + delim + PreferShiftHere() + elem
       plusList.Rule |= listMember;        // rule => list + delim + PreferShiftHere() + elem | elem
       //trailing delimiter
       if (options.IsSet(TermListOptions.AllowTrailingDelimiter) & delimiter != null)
     plusList.Rule |= list + delimiter; // => list + delim + PreferShiftHere() + elem | elem | list + delim
       // set Rule value
       plusList.SetFlag(TermFlags.IsList);
       //If we do not use exra list - we're done, return list.Rule
       if (plusList == list)
     return list.Rule;
       // Let's setup listNonTerminal.Rule using plus-list we just created
       //If we are here, TermListOptions.AllowEmpty is set, so we have star-list
       list.Rule = Empty | plusList;
       plusList.SetFlag(TermFlags.NoAstNode);
       list.SetFlag(TermFlags.IsListContainer); //indicates that real list is one level lower
       return list.Rule;
 }
示例#57
0
 private bool ResolveConflictByPrecedence(ParserState state, BnfTerm conflict)
 {
     var stateData = state.BuilderData;
       if (!conflict.IsSet(TermOptions.UsePrecedence)) return false;
       if (!stateData.ShiftTerms.Contains(conflict)) return false; //it is not shift-reduce
       //first find reduce items
       var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict);
       if (reduceItems.Count > 1) return false; // if it is reduce-reduce conflict, we cannot fix it by precedence
       var reduceItem = reduceItems.First();
       //remove shift action and replace it with operator action
       var oldAction = state.Actions[conflict];
       var action = ParserAction.CreateOperator(oldAction.NewState, reduceItem.Core.Production);
       state.Actions[conflict] = action;
       stateData.ResolvedConflicts.Add(conflict);
       return true;
 }
示例#58
0
 internal static BnfExpression Op_Plus(BnfTerm term1, BnfTerm term2)
 {
     return term1 + term2;
 }
示例#59
0
 public BnfExpression(BnfTerm element)
     : this()
 {
     Data[0].Add(element);
 }
示例#60
0
 private static bool IsMainChild(BnfTerm bnfTerm)
 {
     return !(bnfTerm is KeyTerm) && !(bnfTerm is GrammarHint);
 }