Exemple #1
0
        private StyleASTNode ParseLiteralOrReference(StyleTokenType literalType)
        {
            StyleToken currentToken = tokenStream.Current;

            if (AdvanceIfTokenType(StyleTokenType.At))
            {
                return(ParseConstReference().WithLocation(currentToken));
            }

            string value = AssertTokenTypeAndAdvance(literalType);

            switch (literalType)
            {
            case StyleTokenType.String:
                return(StyleASTNodeFactory.StringLiteralNode(value).WithLocation(currentToken));

            case StyleTokenType.Number:
                return(StyleASTNodeFactory.NumericLiteralNode(value).WithLocation(currentToken));

            case StyleTokenType.Boolean:
                return(StyleASTNodeFactory.BooleanLiteralNode(value).WithLocation(currentToken));

            case StyleTokenType.Identifier:
                return(StyleASTNodeFactory.IdentifierNode(value).WithLocation(currentToken));
            }

            throw new ParseException(currentToken, $"Please add support for this type: {literalType}!");
        }
Exemple #2
0
        private void ParseAnimationOptions(AnimationRootNode rootNode)
        {
            while (tokenStream.HasMoreTokens && !AdvanceIfTokenType(StyleTokenType.BracesClose))
            {
                StyleToken typeToken  = tokenStream.Current;
                string     optionName = AssertTokenTypeAndAdvance(StyleTokenType.Identifier).ToLower();
                bool       typeFound  = false;
                for (int index = 0; index < s_AnimationOptionNames.Length; index++)
                {
                    string name = s_AnimationOptionNames[index].Item1;
                    if (name == optionName)
                    {
                        AssertTokenTypeAndAdvance(StyleTokenType.EqualSign);
                        StyleToken variableToken = tokenStream.Current;

                        AnimationOptionNode optionNode = StyleASTNodeFactory.AnimationOptionNode(s_AnimationOptionNames[index].Item2, ParsePropertyValue());
                        optionNode.WithLocation(variableToken);

                        rootNode.AddOptionNode(optionNode);

                        typeFound = true;

                        break;
                    }
                }

                if (!typeFound)
                {
                    throw new ParseException(typeToken, $"{optionName} is not a supported animation option. Valid values are: {FormatOptionList(s_AnimationOptionNames)}\n");
                }

                AssertTokenTypeAndAdvance(StyleTokenType.EndStatement);
            }
        }
Exemple #3
0
        private void ParseAttributeGroup()
        {
            AssertTokenTypeAndAdvance(StyleTokenType.AttributeSpecifier);
            AssertTokenTypeAndAdvance(StyleTokenType.Colon);
            StyleToken attributeToken      = tokenStream.Current;
            string     attributeIdentifier = AssertTokenTypeAndAdvance(StyleTokenType.Identifier);
            string     attributeValue      = null;

            if (AdvanceIfTokenType(StyleTokenType.EqualSign))
            {
                attributeValue = tokenStream.Current.value;
                tokenStream.Advance();
            }

            bool invert = groupOperatorStack.Count > 0 && groupOperatorStack.Pop() == StyleOperatorType.Not;

            AttributeNodeContainer andAttribute           = groupExpressionStack.Count > 0 ? groupExpressionStack.Pop() : null;
            AttributeNodeContainer attributeNodeContainer = StyleASTNodeFactory.AttributeGroupRootNode(attributeIdentifier, attributeValue, invert, andAttribute);

            attributeNodeContainer.WithLocation(attributeToken);

            groupExpressionStack.Push(attributeNodeContainer);

            AssertTokenTypeAndAdvance(StyleTokenType.BracketClose);
        }
Exemple #4
0
        private RunNode ParseRunNode(RunCommandType cmdType, RunAction runAction)
        {
            StyleToken  runCommandToken = tokenStream.Current;
            CommandNode command;

            if (AdvanceIfTokenType(StyleTokenType.Animation))
            {
                command = StyleASTNodeFactory.AnimationCommandNode(ParseIdentifierInParentheses(), cmdType, runAction);
            }
            else if (AdvanceIfTokenType(StyleTokenType.Sound))
            {
                command = StyleASTNodeFactory.SoundCommandNode(ParseIdentifierInParentheses(), cmdType, runAction);
            }
            else
            {
                throw new ParseException(runCommandToken,
                                         $"Only animation and sound run commands are supported. Found {runCommandToken}");
            }

            command.WithLocation(tokenStream.Current);
            AssertTokenTypeAndAdvance(StyleTokenType.EndStatement);

            RunNode runNode = StyleASTNodeFactory.RunNode(command);

            runNode.WithLocation(runCommandToken);
            return(runNode);
        }
Exemple #5
0
        internal static StyleStateContainer StateGroupRootNode(StyleToken token)
        {
            StyleStateContainer rootNode = s_StyleContainerNodePool.Get();

            rootNode.type       = StyleASTNodeType.StateGroup;
            rootNode.identifier = token.value;
            rootNode.WithLocation(token);
            return(rootNode);
        }
Exemple #6
0
        private void ParseSpriteSheet()
        {
            StyleToken      initialStyleToken = tokenStream.Current;
            SpriteSheetNode rootNode          = StyleASTNodeFactory.SpriteSheetNode(initialStyleToken);

            rootNode.WithLocation(initialStyleToken);
            tokenStream.Advance();
            AssertTokenTypeAndAdvance(StyleTokenType.BracesOpen);
            SpriteSheetParseLoop(rootNode);
            nodes.Add(rootNode);
        }
Exemple #7
0
        private void ParseExportNode()
        {
            StyleToken exportToken = tokenStream.Current;

            tokenStream.Advance();
            // export statement must be followed by const keyword

            // now let's find out which value we're assigning
            nodes.Add(StyleASTNodeFactory.ExportNode(ParseConstNode()).WithLocation(exportToken));
            AdvanceIfTokenType(StyleTokenType.EndStatement);
        }
Exemple #8
0
        private void ParseAnimation()
        {
            StyleToken        initialStyleToken = tokenStream.Current;
            AnimationRootNode animRoot          = StyleASTNodeFactory.AnimationRootNode(initialStyleToken);

            animRoot.WithLocation(initialStyleToken);
            tokenStream.Advance();
            AssertTokenTypeAndAdvance(StyleTokenType.BracesOpen);
            AnimationParseLoop(animRoot);
            nodes.Add(animRoot);
        }
Exemple #9
0
        private void ParseSound()
        {
            StyleToken    soundNameToken = tokenStream.Current;
            SoundRootNode soundRootNode  = StyleASTNodeFactory.SoundRootNode(soundNameToken);

            soundRootNode.WithLocation(soundNameToken);
            tokenStream.Advance();
            AssertTokenTypeAndAdvance(StyleTokenType.BracesOpen);
            SoundParseLoop(soundRootNode);
            nodes.Add(soundRootNode);
        }
Exemple #10
0
        /// <summary>
        /// Takes on all the things after a 'style' keyword on the root level of a style file.
        /// </summary>
        /// <exception cref="ParseException"></exception>
        private void ParseStyle()
        {
            string     identifier        = null;
            string     tagName           = null;
            StyleToken initialStyleToken = tokenStream.Current;

            switch (initialStyleToken.styleTokenType)
            {
            // <TagName> { ... }
            case StyleTokenType.LessThan:
                tokenStream.Advance();
                AssertTokenType(StyleTokenType.Identifier);
                tagName = tokenStream.Current.value;
                tokenStream.Advance();
                if (tokenStream.Current.styleTokenType == StyleTokenType.LessThan)
                {
                    tagName += tokenStream.Current.value;
                    tokenStream.Advance();
                    tagName += tokenStream.Current.value;
                    AssertTokenTypeAndAdvance(StyleTokenType.Identifier);
                    tagName += tokenStream.Current.value;
                    AssertTokenTypeAndAdvance(StyleTokenType.GreaterThan);
                }

                AssertTokenTypeAndAdvance(StyleTokenType.GreaterThan);
                break;

            // styleId { ... }
            case StyleTokenType.Identifier:
                identifier = tokenStream.Current.value;
                tokenStream.Advance();
                break;

            default:
                throw new ParseException(initialStyleToken, $"Expected style definition or tag name but found {initialStyleToken.styleTokenType}");
            }

            StyleRootNode styleRootNode = StyleASTNodeFactory.StyleRootNode(identifier, tagName);

            styleRootNode.WithLocation(initialStyleToken);
            nodes.Add(styleRootNode);

            // we just read an element name or style name
            // now move forward and expect an open curly brace

            // next there should be one of those:
            // - property
            // - state
            // - attribute with or without boolean modifier
            // - expression with constants
            ParseStyleGroupBody(styleRootNode);
        }
Exemple #11
0
        private void ParseSoundProperty(SoundRootNode soundRootNode)
        {
            string propertyName = AssertTokenTypeAndAdvance(StyleTokenType.Identifier);

            AssertTokenTypeAndAdvance(StyleTokenType.EqualSign);
            StyleToken variableToken = tokenStream.Current;

            SoundPropertyNode propertyNode = StyleASTNodeFactory.SoundPropertyNode(propertyName, ParsePropertyValue());

            propertyNode.WithLocation(variableToken);

            soundRootNode.AddChildNode(propertyNode);
            AssertTokenTypeAndAdvance(StyleTokenType.EndStatement);
        }
Exemple #12
0
        private void ParseImportNode()
        {
            StyleToken importToken = tokenStream.Current;

            AssertTokenTypeAndAdvance(StyleTokenType.Import);
            string source = AssertTokenTypeAndAdvance(StyleTokenType.String);

            AssertTokenTypeAndAdvance(StyleTokenType.As);

            string alias = AssertTokenTypeAndAdvance(StyleTokenType.Identifier);

            AssertTokenTypeAndAdvance(StyleTokenType.EndStatement);

            nodes.Add(StyleASTNodeFactory.ImportNode(alias, source).WithLocation(importToken));
        }
Exemple #13
0
        private ConstNode ParseConstNode()
        {
            StyleToken constToken = tokenStream.Current;

            AssertTokenTypeAndAdvance(StyleTokenType.Const);
            // const name
            string variableName = AssertTokenTypeAndAdvance(StyleTokenType.Identifier);

            AssertTokenTypeAndAdvance(StyleTokenType.EqualSign);

            ConstNode constNode = StyleASTNodeFactory.ConstNode(variableName, ParsePropertyValue());

            constNode.WithLocation(constToken);
            return(constNode);
        }
Exemple #14
0
        private UnitNode ParseUnit()
        {
            StyleToken styleToken = tokenStream.Current;
            string     value      = styleToken.value;

            tokenStream.Advance();

            switch (styleToken.styleTokenType)
            {
            case StyleTokenType.Identifier:
                return(StyleASTNodeFactory.UnitNode(value));

            case StyleTokenType.Mod:
                return(StyleASTNodeFactory.UnitNode(value));

            default:
                throw new ParseException(styleToken, "Expected a token that looks like a unit but this didn't.");
            }
        }
Exemple #15
0
        private void ParseAnimationVariables(AnimationRootNode rootNode)
        {
            while (tokenStream.HasMoreTokens && !AdvanceIfTokenType(StyleTokenType.BracesClose))
            {
                StyleToken typeToken      = tokenStream.Current;
                string     typeIdentifier = AssertTokenTypeAndAdvance(StyleTokenType.Identifier);
                bool       typeFound      = false;
                for (int index = 0; index < s_SupportedVariableTypes.Length; index++)
                {
                    (string name, Type type) = s_SupportedVariableTypes[index];
                    if (name == typeIdentifier)
                    {
                        string variableName = AssertTokenTypeAndAdvance(StyleTokenType.Identifier);
                        AssertTokenTypeAndAdvance(StyleTokenType.EqualSign);
                        StyleToken variableToken = tokenStream.Current;

                        VariableDefinitionNode varNode = new VariableDefinitionNode();
                        varNode.name         = variableName;
                        varNode.variableType = type;
                        varNode.value        = ParsePropertyValue();
                        varNode.WithLocation(variableToken);

                        rootNode.AddVariableNode(varNode);

                        typeFound = true;

                        break;
                    }
                }

                if (!typeFound)
                {
                    throw new ParseException(typeToken, "Unsupported Type; please read the manual!");
                }

                AssertTokenTypeAndAdvance(StyleTokenType.EndStatement);
            }
        }
Exemple #16
0
        private StyleASTNode ParsePropertyValue()
        {
            StyleToken   propertyToken = tokenStream.Current;
            StyleASTNode propertyValue;

            switch (tokenStream.Current.styleTokenType)
            {
            case StyleTokenType.Number:
                StyleLiteralNode value = StyleASTNodeFactory.NumericLiteralNode(tokenStream.Current.value).WithLocation(propertyToken) as StyleLiteralNode;
                tokenStream.Advance();
                if (!IsAnyTokenType(StyleTokenType.EndStatement, StyleTokenType.Number, StyleTokenType.Comma, StyleTokenType.ParenClose))
                {
                    UnitNode unit = ParseUnit().WithLocation(tokenStream.Previous) as UnitNode;
                    propertyValue = StyleASTNodeFactory.MeasurementNode(value, unit);
                }
                else
                {
                    propertyValue = value;
                }

                break;

            case StyleTokenType.String:

                propertyValue = StyleASTNodeFactory.StringLiteralNode(tokenStream.Current.value);
                tokenStream.Advance();

                if (tokenStream.Current == StyleTokenType.BracesOpen)
                {
                    TextUtil.StringBuilder.Clear();
                    StyleLiteralNode n = (StyleLiteralNode)propertyValue;

                    TextUtil.StringBuilder.Append("\"");
                    TextUtil.StringBuilder.Append(n.rawValue);
                    TextUtil.StringBuilder.Append("\" ");

                    while (tokenStream.HasMoreTokens && tokenStream.Current != StyleTokenType.BracesClose)
                    {
                        TextUtil.StringBuilder.Append(tokenStream.Current.value);
                        tokenStream.Advance();
                    }

                    TextUtil.StringBuilder.Append(tokenStream.Current.value);

                    tokenStream.Advance();
                    n.rawValue = TextUtil.StringBuilder.ToString();
                    TextUtil.StringBuilder.Clear();
                }

                break;

            case StyleTokenType.Identifier:
                string identifier = tokenStream.Current.value;
                tokenStream.Advance();
                if (tokenStream.Current.styleTokenType == StyleTokenType.ParenOpen)
                {
                    tokenStream.Advance();
                    propertyValue = ParsePropertyFunction(identifier);
                }
                else
                {
                    propertyValue = StyleASTNodeFactory.IdentifierNode(identifier);
                }

                break;

            case StyleTokenType.Rgba:
                propertyValue = ParseRgba();
                break;

            case StyleTokenType.Rgb:
                propertyValue = ParseRgb();
                break;

            case StyleTokenType.HashColor:
                propertyValue = StyleASTNodeFactory.ColorNode(tokenStream.Current.value);
                tokenStream.Advance();
                break;

            case StyleTokenType.Url:
                tokenStream.Advance();
                AssertTokenTypeAndAdvance(StyleTokenType.ParenOpen);

                StyleASTNode url;
                StyleASTNode spriteName = null;
                if (tokenStream.Current.styleTokenType == StyleTokenType.String)
                {
                    url = ParseLiteralOrReference(StyleTokenType.String);
                }
                else
                {
                    url = ParseLiteralOrReference(StyleTokenType.Identifier);
                }

                if (url is StyleIdentifierNode urlIdentifier)
                {
                    // todo -- this doesn't handle spaces!
                    while (tokenStream.HasMoreTokens && !AdvanceIfTokenType(StyleTokenType.ParenClose))
                    {
                        // advancing tokens no matter the type. We want to concatenate all identifiers and slashes of a path again.
                        urlIdentifier.name += tokenStream.Current.value;
                        spriteName          = ParseSpriteName();
                        tokenStream.Advance();
                    }
                }
                else if (url is StyleLiteralNode || url is ConstReferenceNode)
                {
                    spriteName = ParseSpriteName();
                    AssertTokenTypeAndAdvance(StyleTokenType.ParenClose);
                }
                else
                {
                    throw new CompileException(url, "URL could not be parsed.");
                }

                propertyValue = StyleASTNodeFactory.UrlNode(url, spriteName);
                break;

            case StyleTokenType.At:
                propertyValue = ParseConstReference();
                break;

            case StyleTokenType.Dollar:
                propertyValue = ParseVariableReference();
                break;

            default:
                throw new ParseException(propertyToken, "Expected a property value but found no valid token.");
            }

            return(propertyValue.WithLocation(propertyToken));
        }
Exemple #17
0
 public ParseException(StyleToken token, string message = null) :
     base($"Parse error at line {token.line}, column {token.column}, token type '{token.styleTokenType}' -> {token.value}\n{message}")
 {
     this.token = token;
 }
Exemple #18
0
        private void ParseProperty(StyleNodeContainer styleRootNode, bool parsingKeyframes = false)
        {
            StyleToken propertyNodeToken = tokenStream.Current;
            string     propertyName;

            if (AdvanceIfTokenType(StyleTokenType.Cursor))
            {
                propertyName = propertyNodeToken.value;
            }
            else if (AdvanceIfTokenType(StyleTokenType.Run))
            {
                styleRootNode.AddChildNode(ParseRunNode(RunCommandType.Enter, RunAction.Run));
                return;
            }
            else if (AdvanceIfTokenType(StyleTokenType.Pause))
            {
                styleRootNode.AddChildNode(ParseRunNode(RunCommandType.Enter, RunAction.Pause));
                return;
            }
            else if (AdvanceIfTokenType(StyleTokenType.Stop))
            {
                styleRootNode.AddChildNode(ParseRunNode(RunCommandType.Enter, RunAction.Stop));
                return;
            }
            else if (AdvanceIfTokenType(StyleTokenType.BracketOpen))
            {
                if (TryParseCommand(styleRootNode))
                {
                    return;
                }

                throw new ParseException(tokenStream.Current, "Not sure what you tried here but at this point only [enter] and [exit] run animation would be legal.");
            }
            else
            {
                propertyName = AssertTokenTypeAndAdvance(StyleTokenType.Identifier);

                if (propertyName == "material" || propertyName == "Material")
                {
                    if (tokenStream.Current == StyleTokenType.Colon)
                    {
                        tokenStream.Advance();

                        string materialName = AssertTokenTypeAndAdvance(StyleTokenType.Identifier);

                        AssertTokenTypeAndAdvance(StyleTokenType.Dot);

                        string materialPropertyName = AssertTokenTypeAndAdvance(StyleTokenType.Identifier);

                        AssertTokenTypeAndAdvance(StyleTokenType.EqualSign);

                        TextUtil.StringBuilder.Clear();

                        while (tokenStream.HasMoreTokens && tokenStream.Current != StyleTokenType.EndStatement)
                        {
                            TextUtil.StringBuilder.Append(tokenStream.Current.value);
                            tokenStream.Advance();
                        }

                        tokenStream.Advance();

                        MaterialPropertyNode materialPropertyNode = new MaterialPropertyNode {
                            materialName = materialName,
                            identifier   = materialPropertyName,
                            value        = TextUtil.StringBuilder.ToString()
                        };

                        TextUtil.StringBuilder.Clear();

                        materialPropertyNode.WithLocation(propertyNodeToken);
                        styleRootNode.AddChildNode(materialPropertyNode);
                        return;
                    }
                }
            }

            AssertTokenTypeAndAdvance(StyleTokenType.EqualSign);

            PropertyNode propertyNode = StyleASTNodeFactory.PropertyNode(propertyName);

            propertyNode.WithLocation(propertyNodeToken);

            while (tokenStream.HasMoreTokens && !AdvanceIfTokenType(StyleTokenType.EndStatement))
            {
                propertyNode.AddChildNode(ParsePropertyValue());
                // we just ignore the comma for now
                AdvanceIfTokenType(StyleTokenType.Comma);
            }

            styleRootNode.AddChildNode(propertyNode);
        }
Exemple #19
0
 public StyleASTNode WithLocation(StyleToken token)
 {
     this.line   = token.line;
     this.column = token.column;
     return(this);
 }