public void ApplyPrematchData(Pred pred, DList <Prematched> path) { _path = path; _index = 0; _reachedInnerAlts = false; pred.Call(this); }
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; }
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); }
public GrammarPos(Pred pred, GrammarPos @return, bool inFollowSet = false) { Debug.Assert(pred != null); Pred = pred; Return = @return; InFollowSet = inFollowSet; }
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; }
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)); } } }
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); }
public override void VisitOther(Pred pred) { if (pred.VarLabel != null) { ProperLabels[pred.VarLabel] = ProperLabels.TryGetValue(pred.VarLabel, false) | pred.ResultSaver == null; } }
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)); } }
public Transition(Pred prevPosition, IPGTerminalSet set, VList <AndPred> andPreds, GrammarPos position) { PrevPosition = prevPosition; Debug.Assert(position != null); Set = set; Position = position; AndPreds = andPreds; }
public static Pred SendValueTo(string funcName, Pred pred) { pred.ResultSaver = res => { // $funcName($res) return(F.Call(GSymbol.Get(funcName), res)); }; return(pred); }
void VisitWithNewTarget(Pred toBeVisited, WList <LNode> target) { var old = _target; _target = target; Visit(toBeVisited); _target = old; }
new public void Visit(Pred pred) { var old = _currentPred; _currentPred = pred; pred.Call(this); _currentPred = old; }
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; } }
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 }); }
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]; } }
private void Append(Pred pred) { if (pred is Seq) { List.AddRange((pred as Seq).List); } else { List.Add(pred); } }
private bool VisitAndReplace(ref Pred p) { Debug.Assert(Replacement == null); p.Call(this); if (Replacement != null) { p = Replacement; Replacement = null; return(true); } return(false); }
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); } }
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)); } }
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); }
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); }
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)); }
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); } }
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); } }
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++; } }
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); } }
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; } }
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 }); }
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)); } } }