-
-
Save eddwo/5442170 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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