Skip to content

Instantly share code, notes, and snippets.

@dhowe
Last active October 24, 2018 08:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dhowe/0bd17c5a7658ebbc817a1ee5a89aeb19 to your computer and use it in GitHub Desktop.
Save dhowe/0bd17c5a7658ebbc817a1ee5a89aeb19 to your computer and use it in GitHub Desktop.
using System;
using Superpower;
using Superpower.Parsers;
using Superpower.Tokenizers;
using System.Linq;
using Superpower.Display;
using Superpower.Model;
namespace FirstInLine
{
public class Node
{
public string Actor = "";
public string Text = "";
public override string ToString() => Actor + " " + Text;
}
public class TestParser
{
static Tokenizer<Tokens> tokenizer = new TokenizerBuilder<Tokens>()
.Match(Span.EqualTo("()"), Tokens.OpenCloseParen)
.Match(Character.EqualTo('('), Tokens.LParen)
.Match(Character.EqualTo(')'), Tokens.RParen)
.Match(Character.EqualTo('#'), Tokens.Hash)
.Match(Character.EqualTo('$'), Tokens.Dollar)
.Match(Character.EqualTo('.'), Tokens.Dot)
.Match(Character.EqualTo('|'), Tokens.Pipe)
.Match(Character.EqualTo(':'), Tokens.Colon)
.Match(Character.EqualTo(' '), Tokens.Whitespace)
.Match(Span.MatchedBy(Character.AnyChar), Tokens.String)
.Match(Numerics.Natural, Tokens.Number)
.Build();
public static void Out(TokenList<Tokens> vals)
{
var count = 0;
foreach (var v in vals)
{
Console.WriteLine((count++) + ": " + v.Kind + "='" + v.Span + "'");
}
Console.WriteLine();
}
static void Main(string[] args)
{
string[] input = { "A: Hello Goodbye", "Goodbye A: Hello" };
var tokens = tokenizer.Tokenize(input[0]);
var result = NodeParser.TryParse(tokens);
if (result.HasValue)
{
Node node = (Node)result.Value; // valid
Console.WriteLine(node.Actor.Equals("A:") ? "OK" : "FAIL");
Console.WriteLine(node.Text.Equals(" Hello Goodbye") ? "OK" : "FAIL");
}
else
{
Console.WriteLine("FAIL: NO VALUE"); // invalid
}
tokens = tokenizer.Tokenize(input[1]);
result = NodeParser.TryParse(tokens);
if (result.HasValue)
{
Node node = (Node)result.Value; // valid
Console.WriteLine("'"+node.Actor+"' '"+node.Text+"'");
Console.WriteLine(node.Actor.Equals("") ? "OK" : "FAIL");
Console.WriteLine(node.Text.Equals("Goodbye A: Hello") ? "OK" : "FAIL");
}
else
{
Console.WriteLine("FAIL: NO VALUE"); // invalid
}
}
public readonly static TokenListParser<Tokens, string> TextParser =
from tokens in Token.EqualTo(Tokens.OpenCloseParen)
.Or(Token.EqualTo(Tokens.Hash))
.Or(Token.EqualTo(Tokens.Dollar))
.Or(Token.EqualTo(Tokens.Dot))
.Or(Token.EqualTo(Tokens.Number))
.Or(Token.EqualTo(Tokens.Colon))
.Or(Token.EqualTo(Tokens.String))
.Or(Token.EqualTo(Tokens.Whitespace))
.Many()
select string.Join("", tokens.Select(t => t.ToStringValue()));
public readonly static TokenListParser<Tokens, string> NameParser =
from tokens in Token.EqualTo(Tokens.OpenCloseParen)
.Or(Token.EqualTo(Tokens.Hash))
.Or(Token.EqualTo(Tokens.Dollar))
.Or(Token.EqualTo(Tokens.Dot))
.Or(Token.EqualTo(Tokens.Number))
.Or(Token.EqualTo(Tokens.String))
.Many()
select string.Join("", tokens.Select(t => t.ToStringValue()));
public readonly static TokenListParser<Tokens, string> ActorParser =
from name in NameParser
from colon in Token.EqualTo(Tokens.Colon)
// where name.Position() == 0
select name != null ? name + colon.ToStringValue(): "";
public readonly static TokenListParser<Tokens, Node> NodeParser =
from actor in ActorParser.OptionalOrDefault("")
from text in TextParser.OptionalOrDefault("")
select new Node { Actor = actor+"", Text = text+"" };
}
public enum Tokens
{
None,
String,
Number,
[Token(Example = "()")]
OpenCloseParen,
[Token(Example = ":")]
Colon,
[Token(Example = "(")]
LParen,
[Token(Example = ")")]
RParen,
[Token(Example = "#")]
Hash,
[Token(Example = "$")]
Dollar,
[Token(Example = "|")]
Pipe,
[Token(Example = ".")]
Dot,
[Token(Example = " ")]
Whitespace,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment