Exemplo n.º 1
0
        public static Parser GetParser()
        {
            // XML chars
            var charLt    = Char['<'];
            var charGt    = Char['>'];
            var charSlash = Char['/'];

            // int expr chars
            var charPlus     = Char['+'];
            var charMinus    = Char['-'];
            var charMult     = Char['*'];
            var charDiv      = Char['/'];
            var charLPar     = Char['('];
            var charRPar     = Char[')'];
            var charDigit    = Char['0', '9'];
            var charAddtOper = CharSet[charPlus + charMinus];
            var charMultOper = CharSet[charMult + charDiv];
            var charOper     = CharSet[charAddtOper + charMultOper];

            // int operator priorities
            int priorityInfixAddt  = 10;
            int priorityInfixMult  = 20;
            int priorityPrefixAddt = 30;

            // token: number
            var exprNum = new Token(IdNum,
                                    charDigit.Repeat() & !LookAhead[SkipWs & (charDigit | charLPar)])
            {
                new Rule <int>
                {
                    Capture(value => int.Parse(value))
                }
            };

            // token: plus (infix or prefix)
            var exprPlus = new Token(IdExpr,
                                     charPlus & !LookAhead[SkipWs & (charOper | charRPar | charLt)])
            {
                new PrefixRule <int, int>(
                    priority: priorityPrefixAddt,
                    select: t => (t.IsFirst || t.LookBehind().First().Is(IdExprLPar)) &&
                    t.LookAhead().First().Is(IdNum, IdExprLPar))
                {
                    Create((int x) => + x)
                },

                new InfixRule <int, int, int>(priority: priorityInfixAddt)
                {
                    Create((int x, int y) => x + y)
                }
            };

            // token: minus (infix or prefix)
            var exprMinus = new Token(IdExpr,
                                      charMinus & !LookAhead[SkipWs & (charOper | charRPar | charLt)])
            {
                new PrefixRule <int, int>(
                    priority: priorityPrefixAddt,
                    select: t => (t.IsFirst || t.LookBehind().First().Is(IdExprLPar)) &&
                    t.LookAhead().First().Is(IdNum, IdExprLPar))
                {
                    Create((int x) => - x)
                },

                new InfixRule <int, int, int>(priority: priorityInfixAddt)
                {
                    Create((int x, int y) => x - y)
                }
            };

            // token: multiplication
            var exprMult = new Token(IdExpr,
                                     charMult & !LookAhead[SkipWs & (charOper | charRPar | charLt)])
            {
                new InfixRule <int, int, int>(priority: priorityInfixMult)
                {
                    Create((int x, int y) => x * y)
                }
            };

            // token: division
            var exprDiv = new Token(IdExpr,
                                    charDiv & !LookAhead[SkipWs & (charOper | charRPar | charLt)])
            {
                new InfixRule <int, int, int>(priority: priorityInfixMult)
                {
                    Create((int x, int y) => x / y)
                }
            };

            // token: left parenthesis
            var exprLPar = new Token(IdExprLPar,
                                     charLPar & !LookAhead[SkipWs & (charRPar | charLt)])
            {
                new LeftDelimiterRule <string>()
                {
                    Capture(value => value)
                }
            };

            // token: right parenthesis
            var exprRPar = new Token(IdExpr,
                                     charRPar & !LookAhead[SkipWs & (charDigit | charLPar)])
            {
                new RightDelimiterRule <string, int, int>
                {
                    Create((string lPar, int n) => n)
                }
            };

            // int expression
            var numExpr = (exprNum
                           | exprPlus
                           | exprMinus
                           | exprMult
                           | exprDiv
                           | exprLPar
                           | exprRPar).Repeat();

            // token: tag value containing int expression
            var tagValue = new Token(IdTagValue, SkipWs_Disable,
                                     LookAhead[SkipWs & CharSet[~(CharSpace + charLt)]] & numExpr & LookAhead[charLt])
            {
                new Rule <string>
                {
                    Create(IdNum, (int expr) => "=" + expr.ToString()),
                    Create(IdExpr, (int expr) => "=" + expr.ToString())
                }
            };

            // token: tag open (only tag name, no attribs)
            var tagBegin = new Token(IdTagBegin,
                                     charLt & new Token(IdTagName, CharWord.Repeat()) & charGt)
            {
                new LeftDelimiterRule <string>
                {
                    Create(IdTagName, (string tagName) => tagName)
                }
            };

            // token: tag close
            var tagEnd = new Token(IdTag,
                                   charLt & charSlash & new Token(IdTagName, CharWord.Repeat()) & LookAhead[charGt])
            {
                new RightDelimiterRule <string, string, string>
                {
                    Create(IdTagName, (string name) => name),
                    Error(
                        (string tag, string tagName) => tagName != tag,
                        (tag, tagName) => string.Format("Expected {0}, found {1}", tagName, tag)),
                    Create(
                        (string tag, string value) => value.StartsWith("="),
                        (tag, value) => tag + value),
                    Create(
                        (string tag, string value) => !value.StartsWith("="),
                        (tag, value) => tag + ":{" + value + "}")
                }
            };

            // token: tag sequence
            var tagConcat = new Token(IdTag, charGt & LookAhead[SkipWs & charLt & ~charSlash])
            {
                new InfixRule <string, string, string>(
                    pre: t => t.LeftOperand.Is(IdTag) && t.RightOperand.Is(IdTag))
                {
                    Create((string leftTag, string rightTag) => leftTag + "," + rightTag)
                }
            };

            // XML containing int expressions
            var xmlInt = StartOfLine
                         & (tagBegin | tagValue | tagEnd & (tagConcat | charGt)).Repeat()
                         & SkipWs & EndOfFile;

            // generate RegExpr parser
            return(xmlInt.Render(CharSpace.Repeat()));
        }
Exemplo n.º 2
0
 public PlayerCharacter(CharSpace charSpace)
 {
     anims          = new PlayerCharacterAnimations();
     this.charSpace = charSpace;
 }