Skip to content

Commit

Permalink
Исправил баг с парсингом signed numbers.
Browse files Browse the repository at this point in the history
  • Loading branch information
sergey-raevskiy committed Sep 3, 2014
1 parent 0256199 commit 3bb794f
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 13 deletions.
59 changes: 46 additions & 13 deletions dwarf-cs/dwarf.core/lang/Lexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,42 @@ internal class NumberRule : ITokenRule
{
public bool Check(char c, int pos)
{
if (pos == 0 && (c == '-' && c == '+'))
return true;
return Char.IsNumber(c);
}

public Token CreateToken(string src)
{
return new ConstantToken(long.Parse(src));
}
}

internal class SignedNumberRule : ITokenRule
{
public bool Check(char c, int pos)
{
if (pos == 0)
return c == '-' || c == '+';
else
return Char.IsNumber(c);
}

public Token CreateToken(string src)
{
return new ConstantToken(long.Parse(src));
long c;

// FIXME: Это по сути затычка для ситуации, когда src не является
// правильной константой, но check возвращает true потому,
// что проверяет только один символ. По сути это ошибка
// дизайна.

if (Int64.TryParse(src, out c))
{
return new ConstantToken(c);
}
else
{
return null;
}
}
}

Expand All @@ -75,10 +102,10 @@ public Token CreateToken(string src)
internal class Matcher
{
private ITokenRule rule;
private bool stop;
private string matched;

public Token Token { get; private set; }
public bool Stop { get; private set; }

public Matcher(ITokenRule rule)
{
Expand All @@ -87,14 +114,14 @@ public Matcher(ITokenRule rule)

public void Reset()
{
stop = false;
Stop = false;
matched = String.Empty;
Token = null;
}

public void Update(char c)
{
if (stop)
if (Stop)
return;

if (rule.Check(c, matched.Length))
Expand All @@ -103,10 +130,10 @@ public void Update(char c)
}
else
{
stop = true;
Stop = true;
}

if (stop && matched.Length > 0)
if (Stop && matched.Length > 0)
{
Token = rule.CreateToken(matched);
}
Expand All @@ -119,6 +146,9 @@ public class Lexer
{
new WhitespaceRule(),

new NumberRule(),
new SignedNumberRule(),

new KeywordRule("if"),
new KeywordRule("then"),
new KeywordRule("else"),
Expand All @@ -143,7 +173,6 @@ public class Lexer
new KeywordRule(":="),

new IdentifierRule(),
new NumberRule(),
};

public IEnumerable<Token> Tokenize(string source)
Expand Down Expand Up @@ -174,12 +203,16 @@ public IEnumerable<Token> Tokenize(string source)
}

Token token = null;
foreach (var matcher in matchers)

if (matchers.All(m => m.Stop))
{
if (matcher.Token != null)
foreach (var matcher in matchers)
{
token = matcher.Token;
break;
if (matcher.Token != null)
{
token = matcher.Token;
break;
}
}
}

Expand Down
19 changes: 19 additions & 0 deletions dwarf-cs/tests/LexerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,24 @@ public void IfThenElseTest()

Assert.AreEqual(expected, actual);
}

[Test]
public void ConstTest()
{
var source = Multiline(
"a := 10",
"a := -12",
"a := +13"
);

var lexer = new Lexer();
var actual = String.Join("", lexer.Tokenize(source));

const string expected = "[a] := <10> " +
"[a] := <-12> " +
"[a] := <13> ";

Assert.AreEqual(expected, actual);
}
}
}

0 comments on commit 3bb794f

Please sign in to comment.