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 override void Visit(RuleRef rref) { var rule = rref.Rule; if (rule.IsPrivate) { rule.Pred.Call(this); } }
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)))); }
public override void Visit(RuleRef pred) { var retType = pred.Rule.ReturnType; if (pred.VarLabel != null) { MaybeCreateVariableFor(pred, pred.VarLabel, retType); } else if (_data.RulesReferenced.Contains(pred.Rule)) { MaybeCreateVariableFor(pred, PickVarNameForRuleName(pred.Rule.Name), retType); } }
public override void Visit(RuleRef rref) { var rule = rref.Rule; if (rule.IsPrivate ?? LLPG.PrematchByDefault) { if (++_ruleDepth < 10) { rule.Pred.Call(this); --_ruleDepth; } } }
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)); } } }
public virtual void Visit(RuleRef rref) { VisitOther(rref); }
public override void Visit(RuleRef rref) { _target.Add(CGH.CallRule(rref, _recognizerMode)); }
public LNode GenerateLexerCode() { _pg = new LLParserGenerator(new IntStreamCodeGenHelper(), MessageSink.Console); // Whitespace & comments var Newline = Rule("Newline", ((C('\r') + Opt(C('\n'))) | '\n') + Stmt("_lineStartAt = InputPosition") + Stmt("_lineNumber++") + Stmt("_value = WhitespaceTag.Value"), Token); var DotIndent = Rule("DotIndent", And("_startPosition == _lineStartAt") + Stmt("_type = TT.Spaces") + Plus(C('.') + Plus(C('\t') | ' ')) + Stmt("_indentLevel = MeasureIndent(_indent = Source.Substring(_startPosition, InputPosition - _startPosition))") + Stmt("_value = WhitespaceTag.Value"), Private); var Spaces = Rule("Spaces", Plus(C(' ') | '\t') + Stmt("if (_lineStartAt == _startPosition) " + "_indentLevel = MeasureIndent(_indent = Source.Substring(_startPosition, InputPosition - _startPosition))") + Stmt("_value = WhitespaceTag.Value"), Token); var SLComment = Rule("SLComment", Seq("//") + Star(Set("[^\r\n]")) + Stmt("_value = WhitespaceTag.Value"), Token); var MLCommentRef = new RuleRef(null, null); var MLComment = Rule("MLComment", Seq("/*") + Star(MLCommentRef / AnyCh, false) + Seq("*/") + Stmt("_value = WhitespaceTag.Value"), Token, 3); MLCommentRef.Rule = MLComment; _pg.AddRules(Newline, DotIndent, Spaces, SLComment, MLComment); // Strings var SQString = Rule("SQString", Stmt("_parseNeeded = false") + C('\'') + ((C('\\') + Set("[^\r\n]") + Stmt("_parseNeeded = true")) / Set("[^'\r\n\\\\]") / (Seq("") + Expr("_parseNeeded = true"))) + Star(Set("[^' \t\n\r]") + Stmt("_parseNeeded = true")) + (C('\'') / (Seq("") + Stmt("_parseNeeded = true"))) + Call("ParseSQStringValue"), Token); var TQString = Rule("TQString", Stmt("_parseNeeded = true") + (Stmt("_style = NodeStyle.Alternate") + Seq(@"""""""") + Star(Seq(@"\\""") / AnyCh, false) + Seq(@"""""""") | Stmt("_style = NodeStyle.Alternate | NodeStyle.Alternate2") + Seq(@"'''") + Star(Seq(@"\\'") / AnyCh, false) + Seq(@"'''")) + Stmt("ParseStringValue(true)"), Token, 4); var DQString = Rule("DQString", Stmt("_parseNeeded = false") + (C('"') + Star(C('\\') + AnyCh + Stmt("_parseNeeded = true") | Set("[^\"\\\\\r\n]")) + '"' | (Stmt("_style = NodeStyle.Alternate") + (Seq(@"#""") + Star((Seq(@"""""") + Stmt("_parseNeeded = true")) / Set("[^\"]")) + '"')) ) + Stmt("ParseStringValue(false)"), Token); var BQString2 = Rule("BQString2", Stmt("_parseNeeded = false") + C('`') + Star(C('\\') + AnyCh + Stmt("_parseNeeded = true") | Set("[^`\\\\\r\n]")) + '`', Private); var BQString = Rule("BQString", BQString2 + Stmt("ParseBQStringValue()"), Token); _pg.AddRules(SQString, DQString, TQString, BQString, BQString2); // Identifiers and symbols var letterTest = F.Call(F.Dot("#char", "IsLetter"), F.Call(S.Cast, F.Id("LA0"), F.Id(S.Char))); var lettersOrPunc = Set(@"[0-9a-zA-Z_'#~!%^&*\-+=|<>/\\?:.$]"); Debug.Assert(!((PGIntSet)lettersOrPunc.Set).Contains('`')); var IdExtLetter = Rule("IdExtLetter", And(letterTest) + Set("[\u0080-\uFFFC]"), Private); var NormalId = Rule("NormalId", (Set("[#_a-zA-Z]") | IdExtLetter) + Star(Set("[#_a-zA-Z0-9']") | IdExtLetter)); var CommentStart = Rule("CommentStart", '/' + (C('/') | '*'), Private); var FancyId = Rule("FancyId", BQString2 | Plus(AndNot(CommentStart) + lettersOrPunc | IdExtLetter)); var Symbol = Rule("Symbol", Stmt("_parseNeeded = false") + Seq("@@") + FancyId + Call("ParseSymbolValue"), Token); var Id = Rule("Id", Stmt("_parseNeeded = false") + (NormalId | '@' + FancyId + Stmt("_parseNeeded = true")) + Call("ParseIdValue"), Private); _pg.AddRules(IdExtLetter, NormalId, CommentStart, FancyId, Symbol, Id); // Punctuation var Comma = Rule("Comma", Op(",", "Comma"), Private); var Semicolon = Rule("Semicolon", Op(";", "Semicolon"), Private); var At = Rule("At", C('@') + Stmt("_type = TT.At; _value = GSymbol.Empty"), Private); var ops = Set(@"[~!%^&*\-+=|<>/?:.$]"); var Operator = Rule("Operator", Plus(AndNot(CommentStart) + ops) + Stmt("ParseNormalOp()"), Private); var BackslashOp = Rule("BackslashOp", '\\' + Opt(FancyId) + Stmt("ParseBackslashOp()"), Private); _pg.AddRules(Comma, Semicolon, At, Operator, BackslashOp); // Openers & closers var LParen = Rule("LParen", C('('), Token); var RParen = Rule("RParen", C(')'), Token); var LBrack = Rule("LBrack", C('['), Token); var RBrack = Rule("RBrack", C(']'), Token); var LBrace = Rule("LBrace", C('{'), Token); var RBrace = Rule("RBrace", C('}'), Token); _pg.AddRules(new[] { LParen, RParen, LBrack, RBrack, LBrace, RBrace }); Rule Number; _pg.AddRules(NumberParts(out Number)); var Shebang = Rule("Shebang", Seq("#!") + Star(Set("[^\r\n]")) + Opt(Newline)); Alts tokenAlts = (Alts)( (And(Expr("InputPosition == 0")) + T(Shebang)) / T(Symbol) / T(Id) / T(Spaces) / T(Newline) / DotIndent / T(SLComment) / T(MLComment) / T(Number) / (Stmt("_type = TT.String") + TQString) / (Stmt("_type = TT.String") + DQString) / T(SQString) / T(BQString) / T(Comma) / T(Semicolon) / T(LParen) / T(LBrack) / T(LBrace) / T(RParen) / T(RBrack) / T(RBrace) / T(At) / BackslashOp / Operator); tokenAlts.DefaultArm = 2; // Id var token = Rule("Token", tokenAlts, Token, 3); _pg.AddRules(new[] { token, Shebang }); _pg.FullLLk = true; //_pg.Verbosity = 3; var members = _pg.Run(F.File); members = members.PlusArgs(SymbolsToDeclare.Select(p => F.Var(F.Id("Symbol"), p.Key, F.Call(F.Dot("GSymbol", "Get"), F.Literal(p.Value.Name))))); return(F.Attr(F.Public, F.Id(S.Partial), F.Call(S.Class, F.Id(_("LesLexer")), F.Tuple(), members))); }