From 3bb794f74fe910d48427952b01f8a475c087d876 Mon Sep 17 00:00:00 2001 From: sergey-raevskiy Date: Wed, 3 Sep 2014 16:59:51 +0400 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B1=D0=B0=D0=B3=20=D1=81=20=D0=BF=D0=B0=D1=80=D1=81?= =?UTF-8?q?=D0=B8=D0=BD=D0=B3=D0=BE=D0=BC=20signed=20numbers.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dwarf-cs/dwarf.core/lang/Lexer.cs | 59 ++++++++++++++++++++++++------- dwarf-cs/tests/LexerTests.cs | 19 ++++++++++ 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/dwarf-cs/dwarf.core/lang/Lexer.cs b/dwarf-cs/dwarf.core/lang/Lexer.cs index 004bc92..de5d1d4 100644 --- a/dwarf-cs/dwarf.core/lang/Lexer.cs +++ b/dwarf-cs/dwarf.core/lang/Lexer.cs @@ -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; + } } } @@ -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) { @@ -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)) @@ -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); } @@ -119,6 +146,9 @@ public class Lexer { new WhitespaceRule(), + new NumberRule(), + new SignedNumberRule(), + new KeywordRule("if"), new KeywordRule("then"), new KeywordRule("else"), @@ -143,7 +173,6 @@ public class Lexer new KeywordRule(":="), new IdentifierRule(), - new NumberRule(), }; public IEnumerable Tokenize(string source) @@ -174,12 +203,16 @@ public IEnumerable 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; + } } } diff --git a/dwarf-cs/tests/LexerTests.cs b/dwarf-cs/tests/LexerTests.cs index ad32038..e89afe0 100644 --- a/dwarf-cs/tests/LexerTests.cs +++ b/dwarf-cs/tests/LexerTests.cs @@ -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); + } } }