mirror of
https://github.com/yck1509/ConfuserEx
synced 2026-06-08 18:29:44 +00:00
94 lines
2.1 KiB
C#
94 lines
2.1 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Text;
|
|
|
|
namespace Confuser.Core.Project {
|
|
internal class PatternTokenizer {
|
|
int index;
|
|
string rulePattern;
|
|
|
|
public void Initialize(string pattern) {
|
|
rulePattern = pattern;
|
|
index = 0;
|
|
}
|
|
|
|
void SkipWhitespace() {
|
|
while (index < rulePattern.Length && char.IsWhiteSpace(rulePattern[index]))
|
|
index++;
|
|
}
|
|
|
|
char? PeekChar() {
|
|
if (index >= rulePattern.Length)
|
|
return null;
|
|
return rulePattern[index];
|
|
}
|
|
|
|
char NextChar() {
|
|
if (index >= rulePattern.Length)
|
|
throw new InvalidPatternException("Unexpected end of pattern.");
|
|
return rulePattern[index++];
|
|
}
|
|
|
|
string ReadLiteral() {
|
|
var ret = new StringBuilder();
|
|
char delim = NextChar();
|
|
Debug.Assert(delim == '"' || delim == '\'');
|
|
|
|
char chr = NextChar();
|
|
while (chr != delim) {
|
|
// Escape sequence
|
|
if (chr == '\\')
|
|
ret.Append(NextChar());
|
|
else
|
|
ret.Append(chr);
|
|
chr = NextChar();
|
|
}
|
|
return ret.ToString();
|
|
}
|
|
|
|
string ReadIdentifier() {
|
|
var ret = new StringBuilder();
|
|
|
|
char? chr = PeekChar();
|
|
while (chr != null && (char.IsLetterOrDigit(chr.Value) || chr == '_' || chr == '-')) {
|
|
ret.Append(NextChar());
|
|
chr = PeekChar();
|
|
}
|
|
|
|
return ret.ToString();
|
|
}
|
|
|
|
public PatternToken? NextToken() {
|
|
if (rulePattern == null)
|
|
throw new InvalidOperationException("Tokenizer not initialized.");
|
|
|
|
SkipWhitespace();
|
|
char? tokenBegin = PeekChar();
|
|
if (tokenBegin == null)
|
|
return null;
|
|
|
|
int pos = index;
|
|
switch (tokenBegin.Value) {
|
|
case ',':
|
|
index++;
|
|
return new PatternToken(pos, TokenType.Comma);
|
|
case '(':
|
|
index++;
|
|
return new PatternToken(pos, TokenType.LParens);
|
|
case ')':
|
|
index++;
|
|
return new PatternToken(pos, TokenType.RParens);
|
|
|
|
case '"':
|
|
case '\'':
|
|
return new PatternToken(pos, TokenType.Literal, ReadLiteral());
|
|
|
|
default:
|
|
if (!char.IsLetter(tokenBegin.Value))
|
|
throw new InvalidPatternException(string.Format("Unknown token '{0}' at position {1}.", tokenBegin, pos));
|
|
|
|
return new PatternToken(pos, TokenType.Identifier, ReadIdentifier());
|
|
}
|
|
}
|
|
}
|
|
} |