public IResult <Token> Parse(ParseState <char> state) { int startConsumed = state.Input.Consumed; var startLocation = state.Input.CurrentLocation; var token = ReadStringToken(state.Input); if (token == null) { return(state.Fail(this, "")); } return(state.Success(this, token, state.Input.Consumed - startConsumed, startLocation)); }
public IResult <string> Parse(ParseState <char> state) { var t = state.Input; int startConsumed = t.Consumed; var a = t.GetNext(); var b = t.Peek(); if (a != '/' || b != '*') { t.PutBack(a); return(state.Fail(this, "")); } var chars = new List <char> { '/', t.GetNext() }; while (true) { var c = t.GetNext(); if (c == '\0') { t.PutBack(c); // TODO: What to do about unexpected end of input? break; } if (c == '*') { if (t.Peek() == '/') { t.GetNext(); chars.Add('*'); chars.Add('/'); break; } } chars.Add(c); } var x = new string(chars.ToArray()); return(state.Success(this, x, t.Consumed - startConsumed)); }
public IResult <Token> Parse(ParseState <char> state) { var input = state.Input; // Attempt to read through an arbitrary c# code literal. We can largely do this by // counting braces, but we have to get a bit more involved when we deal with // braces which are quoted as chars and strings: '{' and "{". // C# is a complicated language and this parser does not want to be complicated. It is expected // that the verbatim contents of this block are passed, opaquely, to roslyn for compilation. // This parser will not attempt in any way to recognize the contents of the C# block or provide // helpful diagnostics/recovery. If the user doesn't balance their {} brackets, they're going // to get an exception and a hard stop. var startConsumed = input.Consumed; var a = input.GetNext(); var b = input.Peek(); if (a != 'c' || b != '#') { input.PutBack(a); return(state.Fail(this, "")); } input.GetNext(); while (char.IsWhiteSpace(input.Peek())) { input.GetNext(); } input.Expect('{'); int braceCount = 1; var buffer = new List <char>(); while (true) { var c = input.GetNext(); if (c == '\0') { TokenizingException.UnexpectedEndOfInput(input.CurrentLocation); } if (c == '\'') { buffer.Add(c); c = input.GetNext(); buffer.Add(c); if (c == '\\') { c = input.GetNext(); buffer.Add(c); c = input.GetNext(); while (c != '\'') { buffer.Add(c); c = input.GetNext(); } } else { c = input.Expect('\''); } buffer.Add(c); continue; } if (c == '"') { buffer.Add(c); while (true) { c = input.GetNext(); if (c == '\0') { TokenizingException.UnexpectedEndOfInput(input.CurrentLocation); } if (c == '"') { break; } if (c == '\\') { buffer.Add(c); c = input.GetNext(); } buffer.Add(c); } buffer.Add(c); continue; } if (c == '@' && input.Peek() == '"') { buffer.Add(c); buffer.Add(input.GetNext()); while (true) { c = input.GetNext(); if (c == '\0') { TokenizingException.UnexpectedEndOfInput(input.CurrentLocation); } if (c == '"') { if (input.Peek() != '"') { break; } buffer.Add(c); c = input.GetNext(); } buffer.Add(c); } buffer.Add(c); continue; } if (c == '{') { braceCount++; buffer.Add(c); continue; } if (c == '}') { braceCount--; if (braceCount == 0) { break; } buffer.Add(c); continue; } buffer.Add(c); } //_chars.Expect('}'); return(state.Success(this, Token.CSharpLiteral(new string(buffer.ToArray())), input.Consumed - startConsumed, input.CurrentLocation)); }