public void Generate(Rule rule) { CGH.BeginRule(rule); _currentRule = rule; _target = new WList<LNode>(); _laVarsNeeded = 0; _separatedMatchCounter = _stopLabelCounter = 0; _recognizerMode = rule.IsRecognizer; _labelsInUse.Clear(); Visit(rule.Pred); if (_laVarsNeeded != 0) { LNode laVars = F.Call(S.Var, CGH.LAType()); for (int i = 0; _laVarsNeeded != 0; i++, _laVarsNeeded >>= 1) if ((_laVarsNeeded & 1) != 0) laVars = laVars.PlusArg(F.Id("la" + i.ToString())); _target.Insert(0, laVars); } LNode method; if (rule.TryWrapperName != null) { Debug.Assert(rule.IsRecognizer); method = F.OnNewLine(CGH.CreateTryWrapperForRecognizer(rule)); _classBody.SpliceAdd(method, S.Splice); } method = CGH.CreateRuleMethod(rule, _target.ToVList()); if (!rule.IsRecognizer) method = F.OnNewLine(method); _classBody.SpliceAdd(method, S.Splice); }
Rule MakeRecognizerVersion(LNode prototype, Symbol newName) { if (IsRecognizer) return this; else { _recognizer = (Rule)MemberwiseClone(); _recognizer.IsRecognizer = true; _recognizer.Basis = prototype; _recognizer.Name = newName; return _recognizer; } }
public static void Run(Rule rule, IMessageSink sink, IDictionary<Symbol, Rule> rules, IPGCodeGenHelper codeGen) { // 1. Scan for a list of code blocks that use $labels, and a list of rules referenced. var data = new DataGatheringVisitor(rules, rule); if (data.RulesReferenced.Count != 0 || data.OtherReferences.Count != 0 || data.ProperLabels.Count != 0) { var vsv = new AutoValueSaverVisitor(data, sink, rules, codeGen); // 2. Create $result variable if it was used // 3. Scan for predicates with labels, and RuleRefs referenced by // code blocks. For each such predicate, generate a variable at // the beginning of the rule and set the ResultSaver. vsv.Process(rule); // 4. Replace recognized $substitutions in code blocks vsv.ReplaceSubstitutionsInCodeBlocks(); } }
public virtual void Done() { _classBody = null; F = null; _setDeclNames = null; _currentRule = null; }
public virtual void BeginRule(Rule rule) { _currentRule = rule; _setNameCounter = 0; }
protected static RuleRef Call(Rule rule, params LNode[] args) { return new RuleRef(null, rule) { Params = new RVList<LNode>(args) }; }
public void Analyze(Rule rule) { rule.Pred.Call(this); // For rules that are not marked "private", we must apply "empty" // prematch information in case the rule is called directly or from // outside the known ruleset, to force use of Match() at rule start. if (!(rule.IsPrivate ?? LLPG.PrematchByDefault)) _apply.ApplyPrematchData(rule.Pred, Empty); }
public void Analyze(Rule rule) { _currentRule = rule; _k = rule.K > 0 ? rule.K : LLPG.DefaultK; rule.Pred.Call(this); }
/// <summary>See <see cref="IPGCodeGenHelper.CreateTryWrapperForRecognizer"/> for more information.</summary> public LNode CreateTryWrapperForRecognizer(Rule rule) { Debug.Assert(rule.TryWrapperName != null); LNode method = rule.GetMethodSignature(); LNode retType = method.Args[0], name = method.Args[1], args = method.Args[2]; RVList<LNode> forwardedArgs = ForwardedArgList(args); LNode lookahead = F.Id("lookaheadAmt"); Debug.Assert(args.Calls(S.List)); args = args.WithArgs(args.Args.Insert(0, F.Var(F.Int32, lookahead))); LNode savePosition = ApiType(F.Id(SavePosition)); LNode @this = InputSource ?? F.@this; LNode body = F.Braces( F.Call(S.UsingStmt, F.Call(S.New, F.Call(savePosition, @this, lookahead)), F.Call(S.Return, F.Call(name, forwardedArgs))) ); return method.WithArgs(retType, rule.TryWrapperName, args, body); }
void TestStage2(bool lexerMode, params Tuple<string,string,string>[] ruleTuples) { var helper = lexerMode ? (IPGCodeGenHelper)new IntStreamCodeGenHelper() : new GeneralCodeGenHelper(); var rules = new List<Pair<Rule,LNode>>(); foreach (var tuple in ruleTuples) { string ruleName = tuple.Item1, inputExpr = tuple.Item2; var node = LesLanguageService.Value.ParseSingle(inputExpr, ConsoleMessageSink.Value, ParsingMode.Expressions); var rule = new Rule(node, GSymbol.Get(ruleName), null); rules.Add(Pair.Create(rule, node)); } var parser = new StageTwoParser(helper, ConsoleMessageSink.Value); parser.Parse(rules); for (int i = 0; i < rules.Count; i++) { var rule = rules[i].A; var ruleAsString = rule.Pred.ToString(); var expected = ruleTuples[i].Item3; if (expected == null) ConsoleMessageSink.Value.Warning(ruleTuples[i].Item1, ruleAsString); else AreEqual(expected, ruleAsString); } }
protected virtual Symbol GenerateSetName(Rule currentRule) { return(GSymbol.Get(string.Format("{0}_set{1}", currentRule.Name.Name, _setNameCounter++))); }
public Rule MakeRecognizerVersion() { var scanName = GSymbol.Get("Scan_" + Name.Name); return _recognizer = _recognizer ?? MakeRecognizerVersion(scanName); }
public DataGatheringVisitor(IDictionary<Symbol, Rule> rules, Rule rule) { _rules = rules; Visit(rule.Pred); }
protected virtual Symbol GenerateSetName(Rule currentRule) { return GSymbol.Get(string.Format("{0}_set{1}", currentRule.Name.Name, _setNameCounter++)); }
public virtual LNode CreateRuleMethod(Rule rule, RVList<LNode> methodBody) { return rule.CreateMethod(methodBody); }
Pred NodeToPredCore(LNode expr, Context ctx = Context.Rule) { if (expr.IsCall) { bool slash = false, not; if (expr.Calls(S.Tuple)) { // sequence: (a, b, c) if (expr.Calls(S.Tuple, 1)) { return(NodeToPred(expr.Args[0], ctx)); } return(ArgsToSeq(expr, ctx)); } else if (expr.Calls(S.Braces)) { // Just code: use an empty sequence var seq = new Seq(expr); seq.PostAction = RemoveBraces(expr); return(seq); } else if (expr.Calls(S.OrBits, 2) || (slash = expr.Calls(S.Div, 2))) { // alternatives: a | b, a || b, a / b LNode lhs = expr.Args[0], rhs = expr.Args[1]; BranchMode lhsMode, rhsMode; Pred left = BranchToPred(lhs, out lhsMode, ctx); Pred right = BranchToPred(rhs, out rhsMode, ctx); return(Pred.Or(left, right, slash, expr, lhsMode, rhsMode, _sink)); } else if (expr.Calls(_Star, 1) || expr.Calls(_Plus, 1) || expr.Calls(_Opt, 1)) { // loop (a+, a*) or optional (a?) return(TranslateLoopExpr(expr, ctx)); } else if (expr.Calls(_Gate, 1) || expr.Calls(_EqGate, 1)) { // => foo (LES-based parser artifact) return(new Gate(expr, new Seq(F._Missing), NodeToPred(expr.Args[0], Context.GateRight)) { IsEquivalency = expr.Calls(_EqGate) }); } else if (expr.Calls(_Gate, 2) || expr.Calls(_EqGate, 2)) { if (ctx == Context.GateLeft) { _sink.Write(Severity.Error, expr, "Cannot use a gate in the left-hand side of another gate"); } return(new Gate(expr, NodeToPred(expr.Args[0], Context.GateLeft), NodeToPred(expr.Args[1], Context.GateRight)) { IsEquivalency = expr.Calls(_EqGate) }); } else if ((not = expr.Calls(_AndNot, 1)) || expr.Calls(_And, 1)) { expr = expr.Args[0]; var subpred = AutoNodeToPred(expr, Context.And); LNode subexpr = subpred as LNode, subexpr0 = subexpr; bool local = false; if (subexpr != null) { if ((subexpr = subexpr.WithoutAttrNamed(_Local)) != subexpr0) { local = true; } // we should default to [Local] eventually, so recognize [Hoist] too subexpr = subexpr.WithoutAttrNamed(_Hoist); } return(new AndPred(expr, subexpr ?? subpred, not, local)); } else if (expr.Calls(S.NotBits, 1)) { var subpred = NodeToPred(expr.Args[0], ctx); if (subpred is TerminalPred) { var term = (TerminalPred)subpred; term.Set = term.Set.Inverted().WithoutEOF(); return(term); } else { _sink.Write(Severity.Error, expr, "The set-inversion operator ~ can only be applied to a single terminal, not a '{0}'", subpred.GetType().Name); return(subpred); } } else if (expr.Calls(_Any, 2) && expr.Args[0].IsId) { return(Translate_any_in_Expr(expr, ctx)); } else if ((expr.Name.Name.EndsWith(":") || expr.Name.Name.EndsWith("=")) && expr.ArgCount == 2) { return(TranslateLabeledExpr(expr, ctx)); } } // expr is an Id, literal, or non-special call Rule rule = TryGetRule(expr); if (rule != null) { //int ruleArgc = rule.Basis.Args[2].ArgCount; //if (expr.ArgCount > ruleArgc) // don't complain about too few args, in case there are default args (I'm too lazy to check) // _sink.Write(MessageSink.Error, expr, "Rule '{0}' takes {1} arguments ({2} given)", rule.Name, ruleArgc, expr.ArgCount); return(new RuleRef(expr, rule) { Params = expr.Args }); } string errorMsg = null; Pred terminal = _helper.CodeToPred(expr, ref errorMsg); if (terminal == null) { errorMsg = errorMsg ?? "LLLPG: unrecognized expression"; terminal = new TerminalPred(expr, _helper.EmptySet); _sink.Write(Severity.Error, expr, errorMsg); } else if (errorMsg != null) { _sink.Write(Severity.Warning, expr, errorMsg); } return(terminal); }
public Rule MakeRecognizerVersion() { var scanName = GSymbol.Get("Scan_" + Name.Name); return(_recognizer = _recognizer ?? MakeRecognizerVersion(scanName)); }
// Step 3 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)); } }