Skip to content

Instantly share code, notes, and snippets.

@eddwo
Forked from eddwo/gist:5423102
Last active December 16, 2015 13:29
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 eddwo/5442170 to your computer and use it in GitHub Desktop.
Save eddwo/5442170 to your computer and use it in GitHub Desktop.
abstract class Comment
{
public abstract void Generate(StringBuilder builder);
public string Generate()
{
StringBuilder builder = new StringBuilder();
this.Generate(builder);
return builder.ToString();
}
}
sealed class Choice : Comment
{
private readonly string[] _words;
private Random _random;
public Choice(params string[] words)
{
_words = words;
_random = new Random();
}
public override void Generate(StringBuilder builder)
{
builder.Append(_words[_random.Next(_words.Length - 1)]);
}
public override string ToString()
{
string choiceWords = "{";
for (int i = 0; i < _words.Length; i++)
{
if (i > 0) choiceWords += '|';
choiceWords += _words[i];
}
choiceWords += '}';
return choiceWords;
}
}
sealed class Sequence : Comment
{
private readonly Comment[] _sequence;
public Sequence(params Comment[] sequence)
{
_sequence = sequence;
}
public override void Generate(StringBuilder builder)
{
foreach (Comment comm in _sequence)
{
comm.Generate(builder);
}
}
public override string ToString()
{
StringBuilder builder = new StringBuilder();
foreach (Comment comm in _sequence)
{
builder.Append(comm.ToString());
}
return builder.ToString();
}
}
sealed class Words : Comment
{
private readonly string _words;
public Words(string words)
{
_words = words;
}
public override void Generate(StringBuilder builder)
{
builder.Append(_words);
}
public override string ToString()
{
return _words;
}
}
class TemplateParser
{
const char _startChoice = '{';
const char _choiceOption = '|';
const char _endSequence = '|';
const char _endChoice = '}';
private readonly char[] _buffer;
private int _charPos;
public TemplateParser(string templateFile)
{
using (TextReader reader = new StreamReader(templateFile))
{
_buffer = reader.ReadToEnd().ToCharArray();
}
}
public IEnumerable<Comment> ParseTemplate()
{
_charPos = 1;
while (_charPos < _buffer.Length)
{
yield return ParseSequence();
}
}
private Sequence ParseSequence()
{
List<Comment> parts = new List<Comment>();
for (; _charPos < _buffer.Length; _charPos++)
{
switch (_buffer[_charPos])
{
case _startChoice:
_charPos++;
parts.Add(ParseChoice());
_charPos--;
break;
case _endSequence:
_charPos++;
return new Sequence(parts.ToArray());
default:
parts.Add(ParseWords());
_charPos--;
break;
}
}
return new Sequence(parts.ToArray());
}
private Choice ParseChoice()
{
int fromPos = _charPos;
List<string> words = new List<string>();
for (_charPos = fromPos; _charPos < _buffer.Length; _charPos++)
{
switch (_buffer[_charPos])
{
case _choiceOption:
words.Add(new String(_buffer, fromPos, _charPos - fromPos));
fromPos = _charPos + 1;
break;
case _endChoice:
words.Add(new String(_buffer, fromPos, _charPos - fromPos));
_charPos++;
return new Choice(words.ToArray());
}
}
return new Choice(words.ToArray());
}
private Words ParseWords()
{
int fromPos = _charPos;
string words = String.Empty;
for (_charPos = fromPos; _charPos < _buffer.Length; _charPos++)
{
switch (_buffer[_charPos])
{
case _startChoice:
case _endSequence:
words = new String(_buffer, fromPos, _charPos - fromPos);
return new Words(words);
}
}
return new Words(words);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment