public static string LexStringLiteral(LexReader reader, IDictionary <char, char> basicEscapes, IDictionary <char, Func <LexReader, string> > advancedEscapes, string openingSequence, string closingSequence, bool escapeClosingByDoubling) { var builder = new StringBuilder(); if (!reader.ContinuesWith(openingSequence)) { return(null); } var startingPos = reader.GetPosition(); string doubleClosingSequence = closingSequence + closingSequence; reader.Consume(openingSequence.Length); while (true) { if (reader.EndOfFile()) { throw new LexException(reader.GetPosition(), "Unexpected end of string literal.").AddPosition(startingPos, "Start of string literal").Freeze(); } if (escapeClosingByDoubling && reader.ContinuesWith(doubleClosingSequence)) { reader.Consume(doubleClosingSequence.Length); builder.Append(doubleClosingSequence); } else if (reader.ContinuesWith(closingSequence)) { reader.Consume(closingSequence.Length); return(builder.ToString()); } else if ((basicEscapes != null || advancedEscapes != null) && reader.ContinuesWith("\\")) { reader.Consume(1); char escape = reader.ConsumeChar(); char replacement; Func <LexReader, string> replacementFunc; if (basicEscapes.TryGetValue(escape, out replacement)) { builder.Append(replacement); } else if (advancedEscapes.TryGetValue(escape, out replacementFunc)) { builder.Append(replacementFunc(reader)); } else { throw new LexException(reader.GetPosition(-1), @"Unrecognized escape sequence: ""\{0}"".".Fmt(escape)); } // could introduce support for other behaviours on unrecognized \x, such as no-escape (\x => \x) or as-is escape (\x => x) } else { builder.Append(reader.ConsumeChar()); } } }
public static string LexStringLiteral(LexReader reader, IDictionary<char, char> basicEscapes, IDictionary<char, Func<LexReader, string>> advancedEscapes, string openingSequence, string closingSequence, bool escapeClosingByDoubling) { var builder = new StringBuilder(); if (!reader.ContinuesWith(openingSequence)) return null; var startingPos = reader.GetPosition(); string doubleClosingSequence = closingSequence + closingSequence; reader.Consume(openingSequence.Length); while (true) { if (reader.EndOfFile()) throw new LexException(reader.GetPosition(), "Unexpected end of string literal.").AddPosition(startingPos, "Start of string literal").Freeze(); if (escapeClosingByDoubling && reader.ContinuesWith(doubleClosingSequence)) { reader.Consume(doubleClosingSequence.Length); builder.Append(doubleClosingSequence); } else if (reader.ContinuesWith(closingSequence)) { reader.Consume(closingSequence.Length); return builder.ToString(); } else if ((basicEscapes != null || advancedEscapes != null) && reader.ContinuesWith("\\")) { reader.Consume(1); char escape = reader.ConsumeChar(); char replacement; Func<LexReader, string> replacementFunc; if (basicEscapes.TryGetValue(escape, out replacement)) builder.Append(replacement); else if (advancedEscapes.TryGetValue(escape, out replacementFunc)) builder.Append(replacementFunc(reader)); else throw new LexException(reader.GetPosition(-1), @"Unrecognized escape sequence: ""\{0}"".".Fmt(escape)); // could introduce support for other behaviours on unrecognized \x, such as no-escape (\x => \x) or as-is escape (\x => x) } else { builder.Append(reader.ConsumeChar()); } } }
public static string Lex0xHexInteger(LexReader reader) { if (!reader.ContinuesWith("0x") && !reader.ContinuesWith("0X")) return null; reader.Consume(2); string result = reader.ConsumeStringWhile(IsHexadecimalDigit); if (result.Length == 0) throw new LexException(reader.GetPosition(-2), "Hexadecimal integers starting with the \"0x\" prefix must have at least one hex digit."); return (result.Length == 0) ? null : result; }
public override Token ParseToken(LexReader reader) { foreach (var tokenstr in _operators) { if (reader.ContinuesWith(tokenstr)) { var start = reader.GetPosition(); reader.Consume(tokenstr.Length); return(new BuiltinToken(start, reader.GetPosition(), tokenstr)); } } return(null); }
public static string Lex0xHexInteger(LexReader reader) { if (!reader.ContinuesWith("0x") && !reader.ContinuesWith("0X")) { return(null); } reader.Consume(2); string result = reader.ConsumeStringWhile(IsHexadecimalDigit); if (result.Length == 0) { throw new LexException(reader.GetPosition(-2), "Hexadecimal integers starting with the \"0x\" prefix must have at least one hex digit."); } return((result.Length == 0) ? null : result); }