示例#1
0
        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));
            }
        }
示例#2
0
                public override void Visit(RuleRef rref)
                {
                    var rule = rref.Rule;

                    if (rule.IsPrivate)
                    {
                        rule.Pred.Call(this);
                    }
                }
示例#3
0
        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))));
        }
示例#4
0
        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);
            }
        }
示例#5
0
                public override void Visit(RuleRef rref)
                {
                    var rule = rref.Rule;

                    if (rule.IsPrivate ?? LLPG.PrematchByDefault)
                    {
                        if (++_ruleDepth < 10)
                        {
                            rule.Pred.Call(this);
                            --_ruleDepth;
                        }
                    }
                }
示例#6
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));
                    }
                }
            }
示例#7
0
 public virtual void Visit(RuleRef rref)
 {
     VisitOther(rref);
 }
示例#8
0
 public override void Visit(RuleRef rref)
 {
     _target.Add(CGH.CallRule(rref, _recognizerMode));
 }
示例#9
0
        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)));
        }