1

I'm trying to parse an array of items, using Sprache library for C# I have a working code that goes like this.

public static Parser<string> Array =
    from open in OpenBrackets.Named("open bracket")
    from items in Literal.Or(Identifier).Or(Array).DelimitedBy(Comma).Optional()
    from close in CloseBrackets.Named("close bracket")
    select open + (items.IsDefined ? string.Join(", ", items.Get()) : " ") + close;

where "Literal" is a parser for numbers or strings, "Identifier" is a parser for a variable identifier and "Comma" is a parser for a comma token. But if I want the array to allow being empty "[ ]" I need to add the Optional() property and verify if "items" is defined:

select open + (items.IsDefined ? string.Join(", ", items.Get()) : " ") + close;

Is there a better cleaner way to do this for parsing a list of items separated by a separator char, that can be empty (list). That I can reuse with other lists of items.

Sample of input data structure:

[Literal/Identifier/Array] => Value;
[Value] [,Value]* => Array

[public/private] [identifier]; => Declaration;
[public/private] [identifier] [[=] [Value]] => Initialization;
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
xDGameStudios
  • 321
  • 1
  • 13
  • Need to see sample of input data. I suspect the data is JSON and using a JSON parser may be better. Never understood why so many people go to 3rd party libraries when using straight Net Library is usually better. – jdweng Mar 11 '18 at 00:44
  • No I'm not actually trying to parse JSON, I'm trying to parse a custom language script I'm creating (kinda like c# but without hard-typed variables) – xDGameStudios Mar 12 '18 at 10:02

2 Answers2

2

A little cleaner way can be accomplished by GetOrElse method.

select open + string.Join(", ", items.GetOrElse(new string[0])) + close;
Mustafa Gursel
  • 782
  • 1
  • 7
  • 16
0

Try using Regex as in code below :

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {

        const string FILENAME = @"c:\temp\test.txt";
        static void Main(string[] args)
        {
            StreamReader reader = new StreamReader(FILENAME);
            string pattern = @"\[(?'bracketData'[^\]]+)\](?'repeat'[*+])?";
            string line = "";
            while ((line = reader.ReadLine()) != null)
            {
                line = line.Trim();
                if (line.Length > 0)
                {
                    string suffix = line.Split(new string[] {"=>"}, StringSplitOptions.None).Select(x => x.Trim()).Last();

                    MatchCollection matches = Regex.Matches(line, pattern);

                    var brackets = matches.Cast<Match>().Select(x => new { bracket = x.Groups["bracketData"].Value, repeat = x.Groups["repeat"].Value }).ToArray();

                    Console.WriteLine("Brackets : '{0}'; Suffix : '{1}'", string.Join(",", brackets.Select(x => "(" + x.bracket + ")" + x.repeat )), suffix);
                }
            }
            Console.ReadLine();

        }
    }

}
jdweng
  • 33,250
  • 2
  • 15
  • 20