Ejemplo n.º 1
0
        private void ParseArgument(MapLexer lexer, MapParserContext context, MappedDataExpression expression)
        {
            // We should have an identifier...
            // TODO - literals
            var ident = CompoundIdentifier.Parse(lexer);

            // The identifier is either an attribute or a model...
            if (ident.HasPrefix)
            {
                expression.Arguments.Add(new MappedDataArgument(context.Resolve(ident)));
            }
            else
            {
                // A model...look it up and add it...
                var modelId = ident.Parts.First();
                var model   = context.Models.FirstOrDefault(x => x.Id == modelId);

                if (model == null)
                {
                    throw new ParserException(ident, $"Model '{modelId}' not found.");
                }

                expression.Arguments.Add(new MappedDataArgument(model));
            }
        }
Ejemplo n.º 2
0
        private void ParseIgnore(MapParserContext context, MapLexer lexer)
        {
            lexer.Consume(TokenKind.Keyword, "ignore");
            lexer.Consume(TokenKind.LeftCurly);

            while (lexer.Token.Kind == TokenKind.Identifier || lexer.Token.Kind == TokenKind.Keyword)
            {
                var ignoredId        = CompoundIdentifier.Parse(lexer);
                var ignoredAttribute = context.Resolve(ignoredId);

                context.MapList.AddIgnored(ignoredAttribute);

                lexer.Consume(TokenKind.Semicolon);
            }

            lexer.Consume(TokenKind.RightCurly);
        }
Ejemplo n.º 3
0
        public MappedDataExpression Parse(MapLexer lexer, MapParserContext context)
        {
            var expression = new MappedDataExpression();

            // Regardless, we should always start with an identifier. This means that functions
            // are not keywords.
            lexer.VerifyToken(TokenKind.Identifier);

            // If the identifier is a function name, parse a function call...
            if (functions.Contains(lexer.Token.Text))
            {
                ParseFunctionCall(lexer, context, expression);
            }
            else
            {
                // We don't have a function call, it must be an identifier. Parse it...
                var ident    = CompoundIdentifier.Parse(lexer);
                var resolved = context.Resolve(ident);

                expression.Arguments.Add(new MappedDataArgument(resolved));
            }

            return(expression);
        }
Ejemplo n.º 4
0
        private void ParseStatement(MapParserContext context, MapLexer lexer)
        {
            // Constructs:
            //      examples ...
            //      ignore ...
            //      with ...
            //      { statements }
            if (lexer.Token.Kind == TokenKind.Keyword)
            {
                if (lexer.Token.Text == "with")
                {
                    ParseWith(context, lexer);
                    return;
                }
                else if (lexer.Token.Text == "name")
                {
                    ParseName(context, lexer);
                    return;
                }
                else if (lexer.Token.Text == "examples")
                {
                    ParseExamples(context, lexer);
                    return;
                }
                else if (lexer.Token.Text == "ignore")
                {
                    ParseIgnore(context, lexer);
                    return;
                }
                else
                {
                    throw new ParserException($"Unexpected keyword '{lexer.Token.Text}'.", lexer.Token);
                }
            }
            else if (lexer.Token.Kind == TokenKind.LeftCurly)
            {
                lexer.Consume(TokenKind.LeftCurly);

                while (lexer.Token.Kind != TokenKind.RightCurly)
                {
                    ParseStatement(context, lexer);
                }

                lexer.Consume(TokenKind.RightCurly);

                return;
            }

            // Constructs:
            //      ident = model(ident);
            //      ident:ident = ident:ident;
            var lhs = CompoundIdentifier.Parse(lexer);

            lexer.Consume(TokenKind.Equals);

            var rhs = expressionParser.Parse(lexer, context);

            // A little special handling for the model function
            if (rhs.FunctionName == "model")
            {
                var model = rhs.Arguments.First().Model;

                if (model == null)
                {
                    throw new ParserException("The 'model' function requires a model argument.");
                }

                context.AddModelAlias(lhs.Parts.First(), model);

                lexer.Consume(TokenKind.Semicolon);
            }
            else
            {
                var target = context.Resolve(lhs);

                var mapCount = context.MapList.Maps.Where(x => x.TargetAttribute.Equals(target)).Count();
                var mapping  = new ExpressiveMapping(IdNames.Substring(mapCount, 1), target, rhs);

                context.MapList.Maps.Add(mapping);

                if (lexer.Token.Kind == TokenKind.LeftCurly)
                {
                    ParseMappingExtras(context, lexer, mapping);
                }
                else
                {
                    lexer.Consume(TokenKind.Semicolon);
                }
            }
        }