From 2dc04656a3a4e9665cc498deb5dbc882b7d868bb Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Fri, 18 Dec 2020 18:59:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=BD=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Reader/ReaderInterface.php | 22 ++++++++++------- src/Reader/StringReader.php | 39 +++++++++++++++++++------------ tests/Reader/StringReaderTest.php | 22 +++++++++++++++++ 3 files changed, 60 insertions(+), 23 deletions(-) diff --git a/src/Reader/ReaderInterface.php b/src/Reader/ReaderInterface.php index febb39e..c668710 100644 --- a/src/Reader/ReaderInterface.php +++ b/src/Reader/ReaderInterface.php @@ -21,6 +21,7 @@ abstract class ReaderInterface protected $currentPosition = 0; protected $currentLinePosition = 0; protected $nextPosition = 0; + protected $currentToken = ""; /** * 获取下一个字符 @@ -30,14 +31,6 @@ abstract class ReaderInterface */ abstract public function getNextChar(): string; - /** - * 获取当前识别符 - * @return string - * @author Jerry Yan <792602257@qq.com> - * @date 2020/12/18 12:06 - */ - abstract public function getCurrentToken(): string; - /** * 获取下一个识别符 * @return string @@ -93,4 +86,17 @@ abstract class ReaderInterface { $this->reset(); } + + public function getCurrentPosition(): int + { + return $this->currentPosition; + } + public function getNextPosition(): int + { + return $this->nextPosition; + } + public function getCurrentToken(): string + { + return $this->currentToken; + } } \ No newline at end of file diff --git a/src/Reader/StringReader.php b/src/Reader/StringReader.php index 6e6112b..075f7ea 100644 --- a/src/Reader/StringReader.php +++ b/src/Reader/StringReader.php @@ -12,7 +12,6 @@ namespace JerryYan\DSL\Reader; class StringReader extends ReaderInterface { protected $string; - protected $currentToken; public function __construct(string $string) { @@ -29,14 +28,6 @@ class StringReader extends ReaderInterface return mb_substr($this->string, $startAt, 1); } - /** - * @inheritDoc - */ - public function getCurrentToken(): string - { - return $this->currentToken; - } - /** * @inheritDoc */ @@ -45,6 +36,7 @@ class StringReader extends ReaderInterface $curToken = ""; $curPos = $this->nextPosition; while ($curChar = $this->getNextChar($curPos)) { + $curPos++; switch ($curChar) { case " ": // 如果开始的时候就有空白,跳过它 @@ -74,6 +66,7 @@ class StringReader extends ReaderInterface $this->nextPosition++; $this->currentLinePosition++; switch ($curChar) { + // TODO: 注释跳过 case " ": // 如果开始的时候就有空白,跳过它 if (empty($curToken)) { @@ -83,18 +76,18 @@ class StringReader extends ReaderInterface // 否则就结束(已经匹配完成) break 2; case "\r": - if ($this->getNextChar($this->nextPosition+1) === "\n") { + if ($this->getNextChar($this->nextPosition + 1) === "\n") { // CRLF换行 - $this->nextPosition+=2; + $this->nextPosition++; } // CR换行 $this->currentLine++; - $this->currentLinePosition=0; + $this->currentLinePosition = 0; break 2; case "\n": // LF换行 $this->currentLine++; - $this->currentLinePosition=0; + $this->currentLinePosition = 0; break 2; default: $curToken .= $curChar; @@ -109,8 +102,24 @@ class StringReader extends ReaderInterface */ public function skipCurrentLine(): bool { - // TODO: Implement skipCurrentLine() method. - return true; + $curPos = $this->currentPosition; + while ($curChar = $this->getNextChar($curPos)) { + $curPos++; + switch ($curChar) { + case "\r": + if ($this->getNextChar($this->nextPosition + 1) === "\n") { + // CRLF换行 + $curPos++; + } + break 2; + case "\n": + break 2; + } + } + $this->nextPosition = $curPos + 1; + $this->currentLine++; + $this->currentLinePosition = 0; + return $this->moveToNextToken(); } /** diff --git a/tests/Reader/StringReaderTest.php b/tests/Reader/StringReaderTest.php index 304cbea..ecaec5f 100644 --- a/tests/Reader/StringReaderTest.php +++ b/tests/Reader/StringReaderTest.php @@ -24,19 +24,24 @@ class StringReaderTest extends TestCase { $this->reader->reset(); $this->assertEquals('A', $this->reader->getNextChar(), "不匹配"); + $this->assertEquals(1, $this->reader->getCurrentPosition(), "CurPos与预计不符"); $this->readerWithCn->reset(); $this->assertEquals('中', $this->readerWithCn->getNextChar(), "不匹配"); + $this->assertEquals(1, $this->readerWithCn->getCurrentPosition(), "CurPos与预计不符"); } public function testGetCurrentToken() { $this->reader->reset(); $this->assertEquals('Ahhh', $this->reader->getCurrentToken(), "不匹配"); + $this->assertEquals(6, $this->reader->getNextPosition(), "NextPos与预计不符"); $this->readerWithCn->reset(); $this->assertEquals('中文', $this->readerWithCn->getCurrentToken(), "不匹配"); + $this->assertEquals(4, $this->readerWithCn->getNextPosition(), "NextPos与预计不符"); } /** + * 移动至下一个Token * @author Jerry Yan <792602257@qq.com> * @date 2020/12/18 14:16 * @depends testGetNextChar @@ -47,8 +52,25 @@ class StringReaderTest extends TestCase $this->reader->reset(); $this->reader->moveToNextToken(); $this->assertEquals('This', $this->reader->getCurrentToken(), "不匹配"); + $this->assertEquals(7, $this->reader->getCurrentPosition(), "CurPos与预计不符"); $this->readerWithCn->reset(); $this->readerWithCn->moveToNextToken(); $this->assertEquals('这是', $this->readerWithCn->getCurrentToken(), "不匹配"); + $this->assertEquals(5, $this->readerWithCn->getCurrentPosition(), "CurPos与预计不符"); + } + + /** + * 获取下一个Token,重复调用均为同一结果 + * @author Jerry Yan <792602257@qq.com> + * @date 2020/12/18 18:49 + */ + public function testGetNextToken() + { + $this->reader->reset(); + $curPos = $this->readerWithCn->getCurrentPosition(); + $string = $this->reader->getNextToken(); + $this->assertEquals($string, $this->reader->getNextToken(), "不匹配"); + $this->assertEquals($this->reader->getNextToken(), $this->reader->getNextToken(), "不匹配"); + $this->assertEquals($curPos, $this->reader->getCurrentPosition(), "CurPos不可以发生变化"); } }