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);
 }
Ejemplo n.º 2
0
        private void CollectTermsRecursive(BnfTerm term)
        {
            if (_grammarData.AllTerms.Contains(term))
            {
                return;
            }

            _grammarData.AllTerms.Add(term);
            var nt = term as NonTerminal;

            if (nt == null)
            {
                return;
            }

            if (string.IsNullOrEmpty(nt.Name))
            {
                if (!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 (var elemList in nt.Rule.Data)
            {
                for (var i = 0; i < elemList.Count; i++)
                {
                    var child = elemList[i];
                    if (child == null)
                    {
                        _language.Errors.Add(GrammarErrorLevel.Error, null, Resources.ErrRuleContainsNull, nt.Name, i);
                        continue;
                    }
                    //Check for nested expression - convert to non-terminal
                    if (child is BnfExpression expr)
                    {
                        child       = new NonTerminal(null, expr);
                        elemList[i] = child;
                    }
                    CollectTermsRecursive(child);
                }
            }
        }
Ejemplo n.º 3
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);
        }
        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);
        }
Ejemplo n.º 5
0
        //Pipe/Alternative
        //New version proposed by the codeplex user bdaugherty
        internal static BnfExpression Op_Pipe(BnfTerm term1, BnfTerm term2)
        {
            BnfExpression expr1 = term1 as BnfExpression;

            if (expr1 == null)
            {
                expr1 = new BnfExpression(term1);
            }
            BnfExpression expr2 = term2 as BnfExpression;

            if (expr2 == null)
            {
                expr2 = new BnfExpression(term2);
            }
            expr1.Data.AddRange(expr2.Data);
            return(expr1);
        }
Ejemplo n.º 6
0
 private ParserAction FindErrorShiftActionInStack(BnfTerm exitTerm)
 {
     while (Context.ParserStack.Count >= 1)
     {
         ParserAction errorShiftAction;
         if (Context.CurrentParserState.Actions.TryGetValue(exitTerm, out errorShiftAction))
         {
             return(errorShiftAction);
         }
         //pop next state from stack
         if (Context.ParserStack.Count == 1)
         {
             return(null); //don't pop the initial state
         }
         Context.ParserStack.Pop();
         Context.CurrentParserState = Context.ParserStack.Top.State;
     }
     return(null);
 }
Ejemplo n.º 7
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);
        }//method
Ejemplo n.º 8
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 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);
        }
Ejemplo n.º 9
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);
        }//method
Ejemplo n.º 10
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;
 }
Ejemplo n.º 11
0
 public BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember)
 {
     return(MakeListRule(listNonTerminal, delimiter, listMember));
 }
Ejemplo n.º 12
0
 public static BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm listMember)
 {
     return(MakePlusRule(listNonTerminal, null, listMember));
 }
Ejemplo n.º 13
0
        }//method

        private void ExecuteShiftTemp(BnfTerm term, ParserAction action)
        {
            Context.ParserStack.Push(new ParseTreeNode(term), action.NewState);
            Context.CurrentParserState = action.NewState;
        }
Ejemplo n.º 14
0
 public BnfExpression(BnfTerm element) : this()
 {
     Data[0].Add(element);
 }
Ejemplo n.º 15
0
 public static BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm listMember) {
   return MakeStarRule(listNonTerminal, null, listMember, TermListOptions.None);
 }
Ejemplo n.º 16
0
        internal ParserState State;  //used by parser to store current state when node is pushed into the parser stack

        public ParseTreeNode(BnfTerm term)
        {
            Term = term;
        }
Ejemplo n.º 17
0
 public BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm listMember)
 {
     return(MakeListRule(listNonTerminal, null, listMember, TermListOptions.StarList));
 }
Ejemplo n.º 18
0
 public ShiftParserAction(BnfTerm term, ParserState newState)
 {
     Term     = term;
     NewState = newState;
 }
Ejemplo n.º 19
0
 public BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember, TermListOptions options)
 {
     return(MakeListRule(listNonTerminal, delimiter, listMember, options | TermListOptions.StarList));
 }
Ejemplo n.º 20
0
 public ParseTreeNode(NonTerminal term, SourceSpan span)  : this()
 {
     Term = term;
     Span = span;
 }
Ejemplo n.º 21
0
        public ParserState GetNextState(BnfTerm shiftTerm)
        {
            var shift = ShiftItems.FirstOrDefault(item => item.Core.Current == shiftTerm);

            return(shift?.ShiftedItem.State);
        }
Ejemplo n.º 22
0
 public static BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember)
 {
     return(MakeStarRule(listNonTerminal, delimiter, listMember, TermListOptions.None));
 }
Ejemplo n.º 23
0
 public ParseTreeNode(ParseTreeNode clone) : this(clone.State)
 {
     Term   = clone.Term;
     Tokens = clone.Tokens;
 }