public virtual LNode CallRule(RuleRef rref, bool recognizerMode) { Rule target = rref.Rule; var @params = rref.Params; if (recognizerMode) { target = target.MakeRecognizerVersion(); // Allow recognizers to take fewer arguments than the normal rule // by truncating argument(s) at the call site. int maxArgCount = target.Basis.CallsMin(S.Fn, 3) ? target.Basis.Args[2].ArgCount : 0; if (@params.Count > maxArgCount) { @params = @params.First(maxArgCount); } } LNode call = F.Call(target.Name, @params); if (recognizerMode) { return(F.Call(S.If, F.Call(S.Not, call), F.Call(S.Return, F.@false))); } else { return(rref.AutoSaveResult(call)); } }
public virtual LNode CallTryRecognizer(RuleRef rref, int lookahead) { Rule target = rref.Rule; target = target.MakeRecognizerVersion(); LNode name = target.TryWrapperName; var @params = rref.Params; return(F.Call(name, @params.Insert(0, F.Literal(lookahead)))); }
private static void ApplyRuleOptions(ref LNode node, Rule rule, IMessageSink sink) { node = node.WithAttrs(node.Attrs.Select(attr => { switch (attr.Name.Name) { case "fullLLk": case "FullLLk": ReadOption <bool>(sink, attr, v => rule.FullLLk = v, true); break; case "#private": case "private": case "priv": case "Private": ReadOption <bool>(sink, attr, v => rule.IsPrivate = v, true); break; case "token": case "Token": ReadOption <bool>(sink, attr, v => rule.IsToken = v, true); break; case "start": case "Start": ReadOption <bool>(sink, attr, v => rule.IsStartingRule = v, true); break; case "#extern": case "extern": case "Extern": ReadOption <bool>(sink, attr, v => rule.IsExternal = v, true); break; case "k": case "K": case "LL": ReadOption <int>(sink, attr, k => rule.K = k, null); break; case "recognizer": case "Recognizer": LNode sig = null; if (attr.ArgCount == 1) { sig = attr.Args[0]; if (sig.Calls(S.Braces, 1)) { sig = sig.Args[0]; } // TODO: we need a way to invoke all applicable macros at a particular location // e.g. "public Foo()::bool;" is not supported by def() alone. sig = LeMP.Prelude.Les.Macros.def(sig, sink) ?? sig; } if (sig != null && sig.CallsMin(S.Fn, 3)) { rule.MakeRecognizerVersion(sig).TryWrapperNeeded(); } else { sink.Write(Severity.Error, sig, "'recognizer' expects one parameter, a method signature."); } break; default: return(attr); } return(null); }).WhereNotNull().ToArray()); }