hex string lexing
This commit is contained in:
parent
a7f81c57cc
commit
f4a8c97e18
|
|
@ -108,4 +108,4 @@ string generateCaseTrie(string[] args ...)
|
||||||
t.add(args[i], args[i+1]);
|
t.add(args[i], args[i+1]);
|
||||||
}
|
}
|
||||||
return printCaseStatements(t, "");
|
return printCaseStatements(t, "");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
107
tokenizer.d
107
tokenizer.d
|
|
@ -395,6 +395,113 @@ unittest
|
||||||
assert (interpretEscapeSequence(k, i) == v);
|
assert (interpretEscapeSequence(k, i) == v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Token lexHexString(R, C = ElementType!R)(ref R input, ref uint index, ref uint lineNumber,
|
||||||
|
const StringStyle style = StringStyle.Escaped)
|
||||||
|
in
|
||||||
|
{
|
||||||
|
assert (input.front == 'x');
|
||||||
|
}
|
||||||
|
body
|
||||||
|
{
|
||||||
|
Token t;
|
||||||
|
t.lineNumber = lineNumber;
|
||||||
|
t.startIndex = index;
|
||||||
|
t.type = TokenType.StringLiteral;
|
||||||
|
auto app = appender!(C[])();
|
||||||
|
if (style & StringStyle.IncludeQuotes)
|
||||||
|
app.put("x\"");
|
||||||
|
input.popFront();
|
||||||
|
input.popFront();
|
||||||
|
index += 2;
|
||||||
|
while (!input.isEoF())
|
||||||
|
{
|
||||||
|
if (isNewline(input))
|
||||||
|
{
|
||||||
|
app.put(popNewline(input, index));
|
||||||
|
++lineNumber;
|
||||||
|
}
|
||||||
|
else if (isHexDigit(input.front))
|
||||||
|
{
|
||||||
|
app.put(input.front);
|
||||||
|
input.popFront();
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
else if (std.uni.isWhite(input.front) && !(style & StringStyle.Escaped))
|
||||||
|
{
|
||||||
|
app.put(input.front);
|
||||||
|
input.popFront();
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
else if (input.front == '"')
|
||||||
|
{
|
||||||
|
if (style & StringStyle.IncludeQuotes)
|
||||||
|
app.put('"');
|
||||||
|
input.popFront();
|
||||||
|
++index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This is an error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!input.isEoF())
|
||||||
|
{
|
||||||
|
switch (input.front)
|
||||||
|
{
|
||||||
|
case 'w':
|
||||||
|
t.type = TokenType.WStringLiteral;
|
||||||
|
goto case 'c';
|
||||||
|
case 'd':
|
||||||
|
t.type = TokenType.DStringLiteral;
|
||||||
|
goto case 'c';
|
||||||
|
case 'c':
|
||||||
|
if (style & StringStyle.IncludeQuotes)
|
||||||
|
app.put(input.front);
|
||||||
|
input.popFront();
|
||||||
|
++index;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (style & StringStyle.Escaped)
|
||||||
|
{
|
||||||
|
auto a = appender!(char[])();
|
||||||
|
foreach (b; std.range.chunks(app.data, 2))
|
||||||
|
a.put(to!string(cast(dchar) parse!uint(b, 16)));
|
||||||
|
t.value = to!string(a.data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
t.value = to!string(app.data);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
uint i;
|
||||||
|
uint l;
|
||||||
|
|
||||||
|
auto a = `x"204041"`;
|
||||||
|
auto ar = lexHexString(a, i, l);
|
||||||
|
assert (ar == " @A");
|
||||||
|
assert (ar == TokenType.StringLiteral);
|
||||||
|
|
||||||
|
auto b = `x"20"w`;
|
||||||
|
auto br = lexHexString(b, i, l);
|
||||||
|
assert (br == " ");
|
||||||
|
assert (br == TokenType.WStringLiteral);
|
||||||
|
|
||||||
|
auto c = `x"6d"`;
|
||||||
|
auto cr = lexHexString(c, i, l, StringStyle.NotEscaped);
|
||||||
|
assert (cr == "6d");
|
||||||
|
|
||||||
|
auto d = `x"5e5f"d`;
|
||||||
|
auto dr = lexHexString(d, i, l, StringStyle.NotEscaped | StringStyle.IncludeQuotes);
|
||||||
|
assert (dr == `x"5e5f"d`);
|
||||||
|
assert (dr == TokenType.DStringLiteral);
|
||||||
|
}
|
||||||
|
|
||||||
Token lexString(R)(ref R input, ref uint index, ref uint lineNumber,
|
Token lexString(R)(ref R input, ref uint index, ref uint lineNumber,
|
||||||
const StringStyle style = StringStyle.Escaped)
|
const StringStyle style = StringStyle.Escaped)
|
||||||
in
|
in
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue