digitalmars.D.learn - parse string as char
- Timothee Cour via Digitalmars-d-learn (9/9) Feb 08 2015 Is there a simple way to parse a string as a char?
- Rikki Cattermole (4/14) Feb 08 2015 Ugh, if you are just wanting to get a singular char in a string just you...
- FG (92/100) Feb 09 2015 parseEscape does something similar to what you need:
- FG (11/11) Feb 09 2015 Of course consuming it dchar by dchar also works:
- Kagamin (1/1) Feb 09 2015 https://github.com/Hackerpilot/libdparse/blob/master/src/std/d/lexer.d#L...
Is there a simple way to parse a string as a char?
eg:
unittest{
assert(parseChar(`a`)=='a');
assert(parseChar(`\n`)=='\n'); //NOTE: I'm looking at `\n` not "\n"
// should also work with other forms of characters, see
http://dlang.org/lex.html
}
Note, std.conv.to doesn't work (`\n`.to!char does not work)
Feb 08 2015
On 9/02/2015 3:40 p.m., Timothee Cour via Digitalmars-d-learn wrote:
Is there a simple way to parse a string as a char?
eg:
unittest{
assert(parseChar(`a`)=='a');
assert(parseChar(`\n`)=='\n'); //NOTE: I'm looking at `\n` not "\n"
// should also work with other forms of characters, see
http://dlang.org/lex.html
}
Note, std.conv.to <http://std.conv.to> doesn't work (`\n`.to!char does
not work)
Ugh, if you are just wanting to get a singular char in a string just you
slices.
assert("mystr"[0] == 'm');
Feb 08 2015
On 2015-02-09 at 03:40, Timothee Cour via Digitalmars-d-learn wrote:
Is there a simple way to parse a string as a char?
eg:
unittest{
assert(parseChar(`a`)=='a');
assert(parseChar(`\n`)=='\n'); //NOTE: I'm looking at `\n` not "\n"
// should also work with other forms of characters, see
http://dlang.org/lex.html
}
Note, std.conv.to <http://std.conv.to> doesn't work (`\n`.to!char does not
work)
parseEscape does something similar to what you need:
https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L3415
Unfortunately it is private and handles only escapes, so here is a modified
version:
import std.range, std.stdio;
dchar parseDchar(Source)(ref Source s)
if (isInputRange!Source && isSomeChar!(ElementType!Source))
{
import std.utf, std.conv;
if (s.front != '\\') {
dchar c = decodeFront(s);
return c;
}
s.popFront;
if (s.empty)
throw new Exception("Unterminated escape sequence");
dchar getHexDigit()(ref Source s_ = s) // workaround
{
import std.ascii : isAlpha, isHexDigit;
if (s_.empty)
throw new Exception("Unterminated escape sequence");
s_.popFront();
if (s_.empty)
throw new Exception("Unterminated escape sequence");
dchar c = s_.front;
if (!isHexDigit(c))
throw new Exception("Hex digit is missing");
return isAlpha(c) ? ((c & ~0x20) - ('A' - 10)) : c - '0';
}
dchar result;
switch (s.front)
{
case '"': result = '\"'; break;
case '\'': result = '\''; break;
case '0': result = '\0'; break;
case '?': result = '\?'; break;
case '\\': result = '\\'; break;
case 'a': result = '\a'; break;
case 'b': result = '\b'; break;
case 'f': result = '\f'; break;
case 'n': result = '\n'; break;
case 'r': result = '\r'; break;
case 't': result = '\t'; break;
case 'v': result = '\v'; break;
case 'x':
result = getHexDigit() << 4;
result |= getHexDigit();
break;
case 'u':
result = getHexDigit() << 12;
result |= getHexDigit() << 8;
result |= getHexDigit() << 4;
result |= getHexDigit();
break;
case 'U':
result = getHexDigit() << 28;
result |= getHexDigit() << 24;
result |= getHexDigit() << 20;
result |= getHexDigit() << 16;
result |= getHexDigit() << 12;
result |= getHexDigit() << 8;
result |= getHexDigit() << 4;
result |= getHexDigit();
break;
default:
throw new Exception("Unknown escape character " ~
to!string(s.front));
}
if (s.empty)
throw new Exception("Unterminated escape sequence");
s.popFront();
return result;
}
dstring parseString(Source)(Source s)
if (isInputRange!Source && isSomeChar!(ElementType!Source))
{
import std.array;
dchar[] result;
auto app = appender(result);
while (!s.empty)
app.put(parseDchar(s));
return app.data;
}
unittest
{
assert(parseString(``) == ""d);
assert(parseString(`abc`) == "abc"d);
assert(parseString(`abc\\n\\n\\n`) == "abc\\n\\n\\n"d);
assert(parseString(`ąćę\\nłńó`) == "ąćę\\nłńó"d);
assert(parseString(`abc\\\nx`) == "abc\\\nx"d);
assert(parseString(`\tabc\r\nx`) == "\tabc\r\nx"d);
assert(parseString(` \x20 `) == " "d);
}
Feb 09 2015
Of course consuming it dchar by dchar also works:
string s = `\tabŁŃ\r\nx`;
assert(parseDchar(s) == '\t');
assert(parseDchar(s) == 'a');
assert(parseDchar(s) == 'b');
assert(parseDchar(s) == 'Ł');
assert(parseDchar(s) == 'Ń');
assert(parseDchar(s) == '\r');
assert(parseDchar(s) == '\n');
assert(parseDchar(s) == 'x');
assert(s.empty);
Feb 09 2015









Rikki Cattermole <alphaglosined gmail.com> 