www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - parse string as char

reply Timothee Cour via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
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
next sibling parent Rikki Cattermole <alphaglosined gmail.com> writes:
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
prev sibling next sibling parent reply FG <home fgda.pl> writes:
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
parent FG <home fgda.pl> writes:
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
prev sibling parent "Kagamin" <spam here.lot> writes:
https://github.com/Hackerpilot/libdparse/blob/master/src/std/d/lexer.d#L1491
Feb 09 2015