简体   繁体   中英

Sprache how to handle multiple line continuation values

I am using Sprache to parse a legacy file.

The file has the following structure very similar to a key and value dictionary:

Entity
{
  propertyA simple
  propertyB 10-1
  propertyC "first"
  propertyD "I am a line that spawns
  to another line"
  propertyE "second"
  propertyF 1,2,3,4,5,6,\
    7,8,9,10,11,\
    12,13,14
  propertyG "one","two","three",\
  "four","five","six","seven",\
  "eight","nine"
}

I am able to process the file correctly but not when it has the "\" line continuation.

The only dirty hack I did is to replace the string sent as input to the parser and replace the characters so there is no line continuation:

public static Document ParseLegsacyFile(string input)
{
     // HACK
     return Document.Parse(input.Replace("\\\r\n", string.Empty));
}

I don't want to carry out this technical debt...

Is there anyway to instruct the parser to ignore the pattern "\" and "\r\n" and replace to a string empty?

I already tried the Except (with Or), Return and Then without much success.

Here is part of the parsers i am using. The following ones are just for the "value" part:

      public static readonly Parser<GenericObject> Value =

        from value in Parse.AnyChar.Until(Parse.LineEnd).Text()

        select new GenericObject(value);



    private static readonly Parser<GenericString> SingleString =

        from result in (from open in Parse.Char(Quote)

            from content in Parse.CharExcept(Quote).Many().Text()

            from close in Parse.Char(Quote)

            select content).Token()

    select new GenericString(result);



   public static readonly Parser<GenericString> StringValue =

       from value in SingleString .DelimitedBy(Parse.Char(Char.Parse(Comma)))

       select new StringLiteral(string.Join(Comma, value));

Old Question, but answer may help someone:

You can remove the continuation char "\" and combine their lines using Sprache as below:

            var text = @"...text here...";
            var result=  RemoveSlash(text).ToList();
           foreach (var l in result)
                Console.WriteLine(l);
        

        IEnumerable<string> RemoveSlash(string text)
        {
            // return;
            Parser<string> Eol = Parse.String("\\" + Environment.NewLine).Text();

            var oneLine = Parse.AnyChar.Until(Parse.LineEnd).Text();
            var multiLine =
                from l in Parse.AnyChar.Until(Eol).Text().Many()
                from c in oneLine.Once()
                let m = string.Join("", l.Concat(c))
                select m;

            var lines = multiLine.Or(oneLine);
            var result = lines.Many().Parse(text);
            return result;

        }

Try it

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM