예제 #1
0
 public void ApplyPrematchData(Pred pred, DList <Prematched> path)
 {
     _path             = path;
     _index            = 0;
     _reachedInnerAlts = false;
     pred.Call(this);
 }
예제 #2
0
파일: Predicates.cs 프로젝트: murven/Loyc
 public Gate(LNode basis, Pred predictor, Pred match) : base(basis)
 {
     G.Require(!(predictor is Gate) && !(match is Gate),
               "A gate '=>' cannot contain another gate");
     Predictor = predictor;
     Match     = match;
 }
예제 #3
0
        private Pred TranslateLabeledExpr(LNode expr, Context ctx)
        {
            var pred = NodeToPred(expr.Args[1], ctx);
            // Note: it's required that we don't change pred.Basis here--
            // AutoValueSaverVisitor expects the Basis of x:'#' to be '#' so
            // that in code blocks $'#' is recognized as being "the same".
            var label     = expr.Args[0];
            var labelName = label.Name;

            if (!label.IsId)
            {
                _sink.Write(Severity.Error, label, "A label must be an identifier");
            }
            else if (labelName == _Inline2 || labelName == _Inline || labelName == _NoInline)
            {
                if (pred is RuleRef)
                {
                    ((RuleRef)pred).IsInline = labelName != _NoInline;
                }
                else
                {
                    _sink.Write(Severity.Error, label, "'{0}:' can only be attached to a rule reference, which '{1}' is not", labelName, pred.ToString());
                }
            }
            else
            {
                var oper = expr.Name;
                pred.VarLabel    = labelName;
                pred.VarIsList   = oper == S.AddSet || oper == _AddColon;
                pred.ResultSaver = Pred.GetStandardResultSaver(label, expr.Name);
            }
            return(pred);
        }
예제 #4
0
파일: KthSet.cs 프로젝트: lydonchandra/Loyc
 public GrammarPos(Pred pred, GrammarPos @return, bool inFollowSet = false)
 {
     Debug.Assert(pred != null);
     Pred        = pred;
     Return      = @return;
     InFollowSet = inFollowSet;
 }
예제 #5
0
파일: KthSet.cs 프로젝트: lydonchandra/Loyc
 public KthSet(Pred start, int alt, IPGTerminalSet emptySet, bool isNongreedyExit = false)
 {
     Cases.Add(new Transition(null, null, new GrammarPos(start, null)));
     Alt             = alt;
     IsNongreedyExit = isNongreedyExit;
     Set             = emptySet;
 }
예제 #6
0
        void Process(Rule rule)
        {
            // Create $result variable if it was used
            bool usingResult = _data.OtherReferences.ContainsKey(_resultId) || _data.ProperLabels.TryGetValue(_result, false);

            if (usingResult && rule.ReturnType != null)
            {
                _data.ProperLabels[_result] = true;
                var type = rule.ReturnType;
                _newVarInitializers[_result] = Pair.Create(type, _codeGen.MakeInitializedVarDecl(type, false, _result));
            }

            Visit(rule.Pred);

            if (_newVarInitializers.Count != 0)
            {
                var   decls  = _newVarInitializers.OrderBy(p => p.Key.Name).Select(p => p.Value.B);
                LNode decls2 = F.Call(S.Splice, decls);
                rule.Pred.PreAction = Pred.MergeActions(decls2, rule.Pred.PreAction);
                if (usingResult)
                {
                    rule.Pred.PostAction = Pred.MergeActions(rule.Pred.PostAction, F.Call(S.Return, _resultId));
                }
            }
        }
예제 #7
0
        private void MaybeCreateVariableFor(Pred pred, Symbol varName, LNode primType)
        {
            if (pred.ResultSaver != null)
            {
                return;
            }
            if (primType == null)
            {
                primType = F.Object;
                _sink.Write(Severity.Error, pred, Localize.From("The type of this expression is unknown (did you set LLLPG's 'terminalType'  option?)"));
            }
            LNode type = primType, oldType;

            if (pred.VarIsList)
            {
                type = _codeGen.GetListType(primType);                 // TODO: allow user-defined list type
            }
            if (!_newVarInitializers.ContainsKey(varName))
            {
                _newVarInitializers[varName] = Pair.Create(type, _codeGen.MakeInitializedVarDecl(primType, pred.VarIsList, varName));
            }
            else if (!(oldType = _newVarInitializers[varName].A).Equals(type))
            {
                _sink.Write(Severity.Error, pred, Localize.From(
                                "Type mismatch: Variable '{0}' was generated earlier with type {1}, but this predicate expects {2}.",
                                varName, oldType, type));
            }
            pred.ResultSaver = Pred.GetStandardResultSaver(F.Id(varName),
                                                           pred.VarIsList ? S.AddSet : S.Assign);
        }
예제 #8
0
 public override void VisitOther(Pred pred)
 {
     if (pred.VarLabel != null)
     {
         ProperLabels[pred.VarLabel] = ProperLabels.TryGetValue(pred.VarLabel, false) | pred.ResultSaver == null;
     }
 }
예제 #9
0
        private Pred TranslateLoopExpr(LNode expr, Context ctx)
        {
            Symbol type   = expr.Name;
            bool?  greedy = null;
            bool   g;

            expr = expr.Args[0];
            if ((g = expr.Calls(_Greedy, 1)) || expr.Calls(_Nongreedy, 1))
            {
                greedy = g;
                expr   = expr.Args[0];
            }
            BranchMode branchMode;
            Pred       subpred = BranchToPred(expr, out branchMode, ctx);

            if (branchMode != BranchMode.None)
            {
                _sink.Write(Severity.Warning, expr, "'default' and 'error' only apply when there are multiple arms (a|b, a/b)");
            }

            if (type == _Star)
            {
                return(new Alts(expr, LoopMode.Star, subpred, greedy));
            }
            else if (type == _Plus)
            {
                return(new Seq(subpred, new Alts(expr, LoopMode.Star, subpred.Clone(), greedy), expr));
            }
            else               // type == _Opt
            {
                return(new Alts(expr, LoopMode.Opt, subpred, greedy));
            }
        }
예제 #10
0
 public Transition(Pred prevPosition, IPGTerminalSet set, VList <AndPred> andPreds, GrammarPos position)
 {
     PrevPosition = prevPosition;
     Debug.Assert(position != null);
     Set      = set;
     Position = position;
     AndPreds = andPreds;
 }
예제 #11
0
 public static Pred SendValueTo(string funcName, Pred pred)
 {
     pred.ResultSaver = res => {
         // $funcName($res)
         return(F.Call(GSymbol.Get(funcName), res));
     };
     return(pred);
 }
예제 #12
0
            void VisitWithNewTarget(Pred toBeVisited, WList <LNode> target)
            {
                var old = _target;

                _target = target;
                Visit(toBeVisited);
                _target = old;
            }
예제 #13
0
            new public void Visit(Pred pred)
            {
                var old = _currentPred;

                _currentPred = pred;
                pred.Call(this);
                _currentPred = old;
            }
예제 #14
0
 public override void VisitOther(Pred pred)
 {
     VisitCode(pred, pred.PreAction);
     VisitCode(pred, pred.PostAction);
     if (pred.VarLabel != null)
     {
         ProperLabels[pred.VarLabel] = ProperLabels.TryGetValue(pred.VarLabel, false) | pred.ResultSaver == null;
     }
 }
예제 #15
0
        private Pred TranslateAndPred(LNode andExpr, bool not)
        {
            var expr = andExpr.Args[0];

            // Distinguish between semantic and syntactic predicates
            LNode subexpr = null;
            Pred  subpred = null;

            if (expr.Calls(S.Braces))
            {
                subexpr = expr.ArgCount == 1 ? expr[0] : expr;
            }
            else
            {
                subpred = NodeToPred(expr, Context.And);
            }
            LNode subexpr0 = subexpr;

            // Extract [Local] or [Hoist] attribute
            bool local = false;

            if (subexpr != null)
            {
                local = true;
                if ((subexpr = subexpr.WithoutAttrNamed(_Hoist)) != subexpr0)
                {
                    local = false;
                }
                // also recognize [Local], which was not the default until v1.9.1
                subexpr = subexpr.WithoutAttrNamed(_Local);
            }

            // Extract error message for Check(), if provided.
            string errorString = null;

            if (subexpr != null)
            {
                subexpr = subexpr.WithAttrs(n => {
                    if (n.Value is string)
                    {
                        errorString = (string)n.Value;
                        return(NoValue.Value);                        // drop attribute from output
                    }
                    else if (n.IsIdNamed("NoCheck"))
                    {
                        errorString = "";
                        return(NoValue.Value);
                    }
                    return(n);
                });
            }

            return(new AndPred(expr, (object)subexpr ?? subpred, not, local)
            {
                CheckErrorMessage = errorString
            });
        }
예제 #16
0
파일: Rule.cs 프로젝트: lydonchandra/Loyc
 public Rule(LNode basis, Symbol name, Pred pred, bool isStartingRule = true)
 {
     Basis          = basis; Pred = pred; Name = name;
     IsStartingRule = isStartingRule;
     EndOfRule      = new EndOfRule(this);
     if (basis != null && basis.Calls(S.Fn) && basis.ArgCount >= 3)
     {
         ReturnType = basis.Args[0];
     }
 }
예제 #17
0
파일: Predicates.cs 프로젝트: dadhi/ecsharp
 private void Append(Pred pred)
 {
     if (pred is Seq)
     {
         List.AddRange((pred as Seq).List);
     }
     else
     {
         List.Add(pred);
     }
 }
예제 #18
0
 private bool VisitAndReplace(ref Pred p)
 {
     Debug.Assert(Replacement == null);
     p.Call(this);
     if (Replacement != null)
     {
         p           = Replacement;
         Replacement = null;
         return(true);
     }
     return(false);
 }
예제 #19
0
            new public void Visit(Pred pred)
            {
                if (pred.PreAction != null && !_recognizerMode)
                {
                    AddUserAction(pred.PreAction);
                }
                var old = _currentPred;

                _currentPred = pred;
                pred.Call(this);
                _currentPred = old;
                if (pred.PostAction != null && !_recognizerMode)
                {
                    AddUserAction(pred.PostAction);
                }
            }
예제 #20
0
파일: Predicates.cs 프로젝트: dadhi/ecsharp
        public static Alts Merge(LNode basis, Pred a, Pred b, bool slashJoined, BranchMode aMode, BranchMode bMode, IMessageSink warnings)
        {
            Alts aAlts = a as Alts, bAlts = b as Alts;

            if (aAlts != null && aMode == BranchMode.None)
            {
                return(aAlts.Insert(basis, slashJoined, true, b, bMode, warnings));
            }
            else if (bAlts != null && bMode == BranchMode.None)
            {
                return(bAlts.Insert(basis, slashJoined, false, a, aMode, warnings));
            }
            else
            {
                return(TwoArms(basis, a, b, slashJoined, aMode, bMode, warnings));
            }
        }
예제 #21
0
        Pred ArgsToSeq(LNode expr, Context ctx)
        {
            List <object> objs   = expr.Args.Select(node => AutoNodeToPred(node, ctx)).ToList();
            Seq           seq    = new Seq(expr);
            LNode         action = null;
            bool          error  = false;

            for (int i = 0; i < objs.Count; i++)
            {
                if (objs[i] is LNode)
                {
                    var code = (LNode)objs[i];
                    if ((ctx == Context.And || ctx == Context.GateLeft) && !error)
                    {
                        error = true;
                        _sink.Write(Severity.Error, objs[i], ctx == Context.And ?
                                    "Cannot use an action block inside an '&' or '!' predicate; these predicates are for prediction only." :
                                    "Cannot use an action block on the left side of a '=>' gate; the left side is for prediction only.");
                    }
                    action = Pred.MergeActions(action, code);
                }
                else                 // Pred
                {
                    Pred pred = (Pred)objs[i];
                    pred.PreAction = Pred.MergeActions(action, pred.PreAction);
                    action         = null;
                    seq.List.Add(pred);
                }
            }
            if (action != null)
            {
                seq.PostAction = action;
            }

            if (seq.List.Count == 1)
            {
                var contents = seq.List[0];
                contents.PreAction  = Pred.MergeActions(seq.PreAction, contents.PreAction);
                contents.PostAction = Pred.MergeActions(seq.PostAction, contents.PostAction);
                return(contents);
            }

            return(seq);
        }
예제 #22
0
파일: Predicates.cs 프로젝트: dadhi/ecsharp
        static Alts OneArm(Pred a, BranchMode aMode)
        {
            var alts = new Alts(a.Basis, LoopMode.None);

            if (aMode == BranchMode.ErrorExit || aMode == BranchMode.ErrorContinue)
            {
                alts.ErrorBranch = a;
                alts.ExitOnError = aMode == BranchMode.ErrorExit;
            }
            else
            {
                alts.Arms.Add(a);
                if (aMode == BranchMode.Default)
                {
                    alts.DefaultArm = 0;
                }
            }
            return(alts);
        }
예제 #23
0
        public override Pred CodeToPred(LNode expr, ref string errorMsg)
        {
            bool     isInt = false;
            PGIntSet set;

            if (expr.IsIdNamed(_underscore))
            {
                set = PGIntSet.AllExceptEOF;
            }
            else if (expr.IsIdNamed(_EOF))
            {
                set = PGIntSet.EOF;
            }
            else if (expr.Calls(S.DotDot, 2))
            {
                int?from = ConstValue(expr.Args[0], ref isInt);
                int?to   = ConstValue(expr.Args[1], ref isInt);
                if (from == null || to == null)
                {
                    errorMsg = "Expected int32 or character literal on each side of «..»";
                    return(null);
                }
                set = PGIntSet.WithRanges(from.Value, to.Value);
            }
            else if (expr.Value is string)
            {
                return(Pred.Seq((string)expr.Value));
            }
            else
            {
                int?num = ConstValue(expr, ref isInt);
                if (num == null)
                {
                    errorMsg = "Unrecognized expression. Expected int32 or character literal instead of: " + expr.ToString();                     // warning
                    return(null);
                }
                set = PGIntSet.With(num.Value);
            }
            set.IsCharSet = !isInt;
            return(new TerminalPred(expr, set, true));
        }
예제 #24
0
        public override void VisitOther(Pred pred)
        {
            LNode basis = pred.Basis;

            if (pred.VarLabel != null)
            {
                basis = null;
                MaybeCreateVariableFor(pred, pred.VarLabel, _codeGen.TerminalType);
            }
            // If code blocks refer to this predicate's label or basis node, tally
            // the reference and create a variable decl for it if we haven't yet.
            // TODO: bug here: LNode equality depends on trivia.
            //       Should we change default definition of LNode equality?
            int predCounter;

            if (_data.OtherReferences.TryGetValueSafe(basis, out predCounter))
            {
                _data.OtherReferences[basis] = predCounter + 1;
                MaybeCreateVariableFor(pred, PickVarNameForLNode(basis), _codeGen.TerminalType);
            }
        }
예제 #25
0
        public Seq(Pred one, Pred two, LNode basis = null) : base(basis)
        {
            if (one is Seq)
            {
                PreAction = one.PreAction;
                List.AddRange((one as Seq).List);
                if (List.Count > 0)
                {
                    var last = List[List.Count - 1];
                    last.PostAction = Pred.MergeActions(last.PostAction, one.PostAction);
                }
                else
                {
                    PreAction = Pred.MergeActions(PreAction, one.PostAction);
                }
            }
            else
            {
                List.Add(one);
            }

            if (two is Seq)
            {
                if (List.Count > 0)
                {
                    var last = List[List.Count - 1];
                    last.PostAction = Pred.MergeActions(last.PostAction, two.PreAction);
                }
                else
                {
                    PreAction = Pred.MergeActions(PreAction, two.PreAction);
                }
                List.AddRange((two as Seq).List);
                PostAction = Pred.MergeActions(PostAction, two.PostAction);
            }
            else
            {
                List.Add(two);
            }
        }
예제 #26
0
파일: Predicates.cs 프로젝트: dadhi/ecsharp
 private void InsertSingle(ref int atIndex, Pred b, BranchMode bMode, IMessageSink warnings)
 {
     if (bMode == BranchMode.ErrorExit || bMode == BranchMode.ErrorContinue)
     {
         if (ErrorBranch != null)
         {
             warnings.Error(b, "There is already an error branch.");
         }
         else
         {
             ErrorBranch = b;
             ExitOnError = bMode == BranchMode.ErrorExit;
             if (atIndex < Arms.Count)
             {
                 Warning_ErrorBranchNotLast(ErrorBranch, warnings);
             }
         }
     }
     else
     {
         if (atIndex == Arms.Count && ErrorBranch != null)
         {
             Warning_ErrorBranchNotLast(ErrorBranch, warnings);
         }
         Arms.Insert(atIndex, b);
         if (bMode == BranchMode.Default)
         {
             if (DefaultArm != null)
             {
                 int a = DefaultArm.Value;
                 warnings.Error(b, "There is already a default branch");
             }
             else
             {
                 DefaultArm = atIndex;
             }
         }
         atIndex++;
     }
 }
예제 #27
0
파일: Predicates.cs 프로젝트: dadhi/ecsharp
 Alts Insert(LNode newBasis, bool slashJoined, bool append, Pred b, BranchMode bMode, IMessageSink warnings)
 {
     if (Mode == LoopMode.None)
     {
         this.Basis = newBasis ?? this.Basis;
         Alts bAlts = b as Alts;
         int  insertAt = append ? this.Arms.Count : 0, boundary = insertAt;
         if (bAlts != null && bMode == BranchMode.None && bAlts.Mode == LoopMode.None)
         {
             for (int i = 0; i < bAlts.Arms.Count; i++)
             {
                 this.InsertSingle(ref insertAt, bAlts.Arms[i], bAlts.DefaultArm == i ? BranchMode.Default : BranchMode.None, warnings);
             }
             if (bAlts.ErrorBranch != null)
             {
                 this.InsertSingle(ref insertAt, bAlts.ErrorBranch, bAlts.ExitOnError ? BranchMode.ErrorExit : BranchMode.ErrorContinue, warnings);
             }
             Debug.Assert(bAlts.DefaultArm != -1);                     // bAlts has no exit branch
         }
         else
         {
             bAlts = null;
             this.InsertSingle(ref insertAt, b, bMode, warnings);
         }
         if (!append)
         {
             boundary = insertAt;
         }
         UpdateSlashDivs(slashJoined, boundary, append, bAlts);
         return(this);
     }
     else
     {
         var copy = OneArm(this, BranchMode.None);
         copy.Insert(newBasis, slashJoined, append, b, bMode, warnings);
         return(copy);
     }
 }
예제 #28
0
파일: Predicates.cs 프로젝트: dadhi/ecsharp
        public Alts(LNode basis, LoopMode mode, Pred contents, bool?greedy = null) : this(basis, mode, greedy)
        {
            Debug.Assert(mode == LoopMode.Star || mode == LoopMode.Opt);
            var contents2 = contents as Alts;

            if (contents2 != null)
            {
                if (contents2.Mode == LoopMode.Opt || contents2.Mode == LoopMode.Star)
                {
                    throw new ArgumentException(Localize.Localized("{0} predicate cannot directly contain {1} predicate", ToStr(mode), ToStr(contents2.Mode)));
                }
                Arms        = contents2.Arms;
                Greedy      = greedy ?? contents2.Greedy;
                _divisions  = contents2._divisions.Clone();
                DefaultArm  = contents2.DefaultArm;
                ErrorBranch = contents2.ErrorBranch;
            }
            else
            {
                Arms.Add(contents);
                Greedy = greedy;
            }
        }
예제 #29
0
 void VisitCode(Pred pred, LNode code)
 {
     if (code == null)
     {
         return;
     }
     code.ReplaceRecursive(node => {
         if (node.Calls(S.Substitute, 1))
         {
             var arg = node.Args[0];
             PredsUsingSubstitution.Add(pred);
             if (arg.IsId && _rules.ContainsKey(arg.Name))
             {
                 RulesReferenced.Add(_rules[arg.Name]);
             }
             else
             {
                 OtherReferences[arg] = 0;
             }
         }
         return(null);                    // search only, no replace
     });
 }
예제 #30
0
            LNode GetAndPredCode(AndPred pred, int lookaheadAmt, LNode laVar)
            {
                if (pred.Pred is LNode)
                {
                    LNode code = (LNode)pred.Pred;

                    // replace $LI and $LA
                    return(code.ReplaceRecursive(arg => {
                        if (arg.Equals(AndPred.SubstituteLA))                         // $LA
                        {
                            return (LNode)laVar;
                        }
                        if (arg.Equals(AndPred.SubstituteLI))                         // $LI
                        {
                            return (LNode)F.Literal(lookaheadAmt);
                        }
                        return null;
                    }));
                }
                else
                {
                    Pred synPred   = (Pred)pred.Pred;                   // Buffalo sumBuffalo = (Buffalo)buffalo.Buffalo;
                    Rule recogRule = LLPG.GetRecognizerRule(synPred);
                    recogRule.TryWrapperNeeded();

                    if (synPred is RuleRef)
                    {
                        return(CGH.CallTryRecognizer(synPred as RuleRef, lookaheadAmt));
                    }
                    else
                    {
                        // Use a temporary RuleRef for this
                        RuleRef rref = new RuleRef(synPred.Basis, recogRule);
                        return(CGH.CallTryRecognizer(rref, lookaheadAmt));
                    }
                }
            }