예제 #1
0
        protected override object EvalAttribute(ParseTree tree, params object[] paramlist)
        {
            Grammar     grammar = (Grammar)paramlist[0];
            Symbol      symbol  = (Symbol)paramlist[1];
            GrammarNode node    = (GrammarNode)paramlist[2];

            if (symbol.Attributes.ContainsKey(node.Nodes[1].Token.Text))
            {
                tree.Errors.Add(new ParseError("Attribute already defined for this symbol: " + node.Nodes[1].Token.Text, 0x1039, node.Nodes[1]));
                return(null);
            }

            symbol.Attributes.Add(node.Nodes[1].Token.Text, (object[])EvalParams(tree, new object[] { node }));
            switch (node.Nodes[1].Token.Text)
            {
            case "Skip":
                if (symbol is TerminalSymbol)
                {
                    grammar.SkipSymbols.Add(symbol);
                }
                else
                {
                    tree.Errors.Add(new ParseError("Attribute for non-terminal rule not allowed: " + node.Nodes[1].Token.Text, 0x1035, node));
                }
                break;

            case "Color":
                if (symbol is NonTerminalSymbol)
                {
                    tree.Errors.Add(new ParseError("Attribute for non-terminal rule not allowed: " + node.Nodes[1].Token.Text, 0x1035, node));
                }

                if (symbol.Attributes["Color"].Length != 1 && symbol.Attributes["Color"].Length != 3)
                {
                    tree.Errors.Add(new ParseError("Attribute " + node.Nodes[1].Token.Text + " has too many or missing parameters", 0x103A, node.Nodes[1]));
                }

                for (int i = 0; i < symbol.Attributes["Color"].Length; i++)
                {
                    if (symbol.Attributes["Color"][i] is string)
                    {
                        tree.Errors.Add(new ParseError("Parameter " + node.Nodes[3].Nodes[i * 2].Nodes[0].Token.Text + " is of incorrect type", 0x103A, node.Nodes[3].Nodes[i * 2].Nodes[0]));
                        break;
                    }
                }
                break;

            case "IgnoreCase":
                if (!(symbol is TerminalSymbol))
                {
                    tree.Errors.Add(new ParseError("Attribute for non-terminal rule not allowed: " + node.Nodes[1].Token.Text, 0x1035, node));
                }
                break;

            case "FileAndLine":
                if (symbol is TerminalSymbol)
                {
                    grammar.SkipSymbols.Add(symbol);
                    grammar.FileAndLine = symbol;
                }
                else
                {
                    tree.Errors.Add(new ParseError("Attribute for non-terminal rule not allowed: " + node.Nodes[1].Token.Text, 0x1035, node));
                }
                break;

            default:
                tree.Errors.Add(new ParseError("Attribute not supported: " + node.Nodes[1].Token.Text, 0x1036, node.Nodes[1]));
                break;
            }

            return(symbol);
        }
예제 #2
0
 public override ParseNode CreateNode(Token token, string text)
 {
     GrammarNode node = new GrammarNode(token, text);
     node.Parent = this;
     return node;
 }
예제 #3
0
        protected override object EvalNameValue(ParseTree tree, params object[] paramlist)
        {
            Grammar     grammer   = (Grammar)paramlist[0];
            Directive   directive = (Directive)paramlist[1];
            GrammarNode node      = (GrammarNode)paramlist[2];

            string key   = node.Nodes[0].Token.Text;
            string value = node.Nodes[2].Token.Text.Substring(1, node.Nodes[2].Token.Text.Length - 2);

            if (value.StartsWith("\""))
            {
                value = value.Substring(1);
            }

            directive[key] = value;

            List <string> names     = new List <string>(new string[] { "Namespace", "OutputPath", "TemplatePath", });
            List <string> languages = new List <string>(new string[] { "c#", "cs", "csharp", "vb", "vb.net", "vbnet", "visualbasic" });

            switch (directive.Name)
            {
            case "TinyPG":
                names.Add("Namespace");
                names.Add("OutputPath");
                names.Add("TemplatePath");
                names.Add("Language");

                if (key == "TemplatePath")
                {
                    if (grammer.GetTemplatePath() == null)
                    {
                        tree.Errors.Add(new ParseError("Template path '" + value + "' does not exist", 0x1060, node.Nodes[2]));
                    }
                }

                if (key == "OutputPath")
                {
                    if (grammer.GetOutputPath() == null)
                    {
                        tree.Errors.Add(new ParseError("Output path '" + value + "' does not exist", 0x1061, node.Nodes[2]));
                    }
                }

                if (key == "Language")
                {
                    if (!languages.Contains(value.ToLower(CultureInfo.InvariantCulture)))
                    {
                        tree.Errors.Add(new ParseError("Language '" + value + "' is not supported", 0x1062, node.Nodes[2]));
                    }
                }
                break;

            case "Parser":
            case "Scanner":
            case "ParseTree":
            case "TextHighlighter":
                names.Add("Generate");
                names.Add("FileName");
                break;

            default:
                return(null);
            }

            if (!names.Contains(key))
            {
                tree.Errors.Add(new ParseError("Directive attribute '" + key + "' is not supported", 0x1034, node.Nodes[0]));
            }

            return(null);
        }