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); }
public override ParseNode CreateNode(Token token, string text) { GrammarNode node = new GrammarNode(token, text); node.Parent = this; return node; }
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); }