diff --git a/Parser/XnParser.cs b/Parser/XnParser.cs index cfb2030..f959107 100644 --- a/Parser/XnParser.cs +++ b/Parser/XnParser.cs @@ -6,10 +6,12 @@ using Sprache; using System.Globalization; using XNeedle.Parser.Elements; using Part = XNeedle.Parser.Elements.Part; +using NullPart = XNeedle.Parser.Elements.NullPart; using XNeedle.Transformation; using Rule = XNeedle.Transformation.Rule; using System.Data; using System.ComponentModel.DataAnnotations; +using System.Text; namespace XNeedle.Parser { @@ -189,16 +191,14 @@ namespace XNeedle.Parser public static CommentParser Comment = new CommentParser { Single = "#", NewLine = Environment.NewLine }; public static readonly Parser BangObject = - from c1 in Comment.SingleLineComment.Optional() from bang in Parse.Char('!') from name in Parse.AnyChar.Until(Parse.Char('(')) from arguments in Argument.DelimitedBy(Parse.Char(',').Token()) from bclose in Parse.Char(')') - let ctx = new Context{XPathSelector = "//*."} + let ctx = new Context{XPathSelector = "//*."} from ws1 in Parse.WhiteSpace.Many().Optional() from open in Parse.Char('{') from ws2 in Parse.WhiteSpace.Many().Optional() - from c2 in Comment.SingleLineComment.Optional() from expressions in Parse.Ref(() => BangObject) .Or(Parse.Ref(() => RuleObject)) .Or(ExprPart(ctx).Select(e => (Part)e)) @@ -209,13 +209,11 @@ namespace XNeedle.Parser select new Bang{Name = new string([.. name]), Arguments = arguments, Body = expressions}; public static readonly Parser RuleObject = - from c1 in Comment.SingleLineComment.Optional() from selector in Selector(XPath).Token() let ctx = new Context{XPathSelector = selector} from ws1 in Parse.WhiteSpace.Many().Optional() from open in Parse.Char('{') from ws2 in Parse.WhiteSpace.Many().Optional() - from c2 in Comment.SingleLineComment.Optional() from expressions in Parse.Ref(() => BangObject) .Or(Parse.Ref(() => RuleObject)) .Or(ExprPart(ctx).Select(e => (Part)e)) @@ -224,6 +222,30 @@ namespace XNeedle.Parser from ws3 in Parse.WhiteSpace.Many().Optional() from close in Parse.Char('}') select new Rule{XPathSelector = selector, Body = expressions}; + + static public string StripComments(string source) + { + var result = new StringBuilder(); + foreach (var line in source.Split('\n')) + { + bool inSingle = false, inDouble = false; + int commentIdx = -1; + for (int i = 0; i < line.Length; i++) + { + char c = line[i]; + if (c == '\'' && !inDouble) inSingle = !inSingle; + else if (c == '"' && !inSingle) inDouble = !inDouble; + else if (c == '#' && !inSingle && !inDouble) + { + commentIdx = i; + break; + } + } + result.Append(commentIdx >= 0 ? line[..commentIdx] : line); + result.Append('\n'); + } + return result.ToString(); + } } } \ No newline at end of file diff --git a/Program.cs b/Program.cs index cd3f6a0..fe57405 100644 --- a/Program.cs +++ b/Program.cs @@ -38,7 +38,9 @@ namespace XNeedle // Auto-discover operations via reflection BangOperation.RegisterAll(); - var masterRule = (Rule)XnParser.RuleObject.Parse(File.ReadAllText(opts.XnDefinition)); + var xnSource = XnParser.StripComments(File.ReadAllText(opts.XnDefinition)); + Console.WriteLine(xnSource); + var masterRule = (Rule)XnParser.RuleObject.Parse(xnSource); var doc = XDocument.Load(opts.Input, LoadOptions.PreserveWhitespace); var encoding = XmlRoundtripWriter.DetectEncoding(File.ReadAllBytes(opts.Input)); var sloc = new SourceLocation(opts.Input, encoding);