This commit is contained in:
2020-12-18 18:59:57 +08:00
parent 7984c42f9e
commit 2dc04656a3
3 changed files with 60 additions and 23 deletions

View File

@ -21,6 +21,7 @@ abstract class ReaderInterface
protected $currentPosition = 0; protected $currentPosition = 0;
protected $currentLinePosition = 0; protected $currentLinePosition = 0;
protected $nextPosition = 0; protected $nextPosition = 0;
protected $currentToken = "";
/** /**
* 获取下一个字符 * 获取下一个字符
@ -30,14 +31,6 @@ abstract class ReaderInterface
*/ */
abstract public function getNextChar(): string; 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 * @return string
@ -93,4 +86,17 @@ abstract class ReaderInterface
{ {
$this->reset(); $this->reset();
} }
public function getCurrentPosition(): int
{
return $this->currentPosition;
}
public function getNextPosition(): int
{
return $this->nextPosition;
}
public function getCurrentToken(): string
{
return $this->currentToken;
}
} }

View File

@ -12,7 +12,6 @@ namespace JerryYan\DSL\Reader;
class StringReader extends ReaderInterface class StringReader extends ReaderInterface
{ {
protected $string; protected $string;
protected $currentToken;
public function __construct(string $string) public function __construct(string $string)
{ {
@ -29,14 +28,6 @@ class StringReader extends ReaderInterface
return mb_substr($this->string, $startAt, 1); return mb_substr($this->string, $startAt, 1);
} }
/**
* @inheritDoc
*/
public function getCurrentToken(): string
{
return $this->currentToken;
}
/** /**
* @inheritDoc * @inheritDoc
*/ */
@ -45,6 +36,7 @@ class StringReader extends ReaderInterface
$curToken = ""; $curToken = "";
$curPos = $this->nextPosition; $curPos = $this->nextPosition;
while ($curChar = $this->getNextChar($curPos)) { while ($curChar = $this->getNextChar($curPos)) {
$curPos++;
switch ($curChar) { switch ($curChar) {
case " ": case " ":
// 如果开始的时候就有空白,跳过它 // 如果开始的时候就有空白,跳过它
@ -74,6 +66,7 @@ class StringReader extends ReaderInterface
$this->nextPosition++; $this->nextPosition++;
$this->currentLinePosition++; $this->currentLinePosition++;
switch ($curChar) { switch ($curChar) {
// TODO: 注释跳过
case " ": case " ":
// 如果开始的时候就有空白,跳过它 // 如果开始的时候就有空白,跳过它
if (empty($curToken)) { if (empty($curToken)) {
@ -83,18 +76,18 @@ class StringReader extends ReaderInterface
// 否则就结束(已经匹配完成) // 否则就结束(已经匹配完成)
break 2; break 2;
case "\r": case "\r":
if ($this->getNextChar($this->nextPosition+1) === "\n") { if ($this->getNextChar($this->nextPosition + 1) === "\n") {
// CRLF换行 // CRLF换行
$this->nextPosition+=2; $this->nextPosition++;
} }
// CR换行 // CR换行
$this->currentLine++; $this->currentLine++;
$this->currentLinePosition=0; $this->currentLinePosition = 0;
break 2; break 2;
case "\n": case "\n":
// LF换行 // LF换行
$this->currentLine++; $this->currentLine++;
$this->currentLinePosition=0; $this->currentLinePosition = 0;
break 2; break 2;
default: default:
$curToken .= $curChar; $curToken .= $curChar;
@ -109,8 +102,24 @@ class StringReader extends ReaderInterface
*/ */
public function skipCurrentLine(): bool public function skipCurrentLine(): bool
{ {
// TODO: Implement skipCurrentLine() method. $curPos = $this->currentPosition;
return true; 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();
} }
/** /**

View File

@ -24,19 +24,24 @@ class StringReaderTest extends TestCase
{ {
$this->reader->reset(); $this->reader->reset();
$this->assertEquals('A', $this->reader->getNextChar(), "不匹配"); $this->assertEquals('A', $this->reader->getNextChar(), "不匹配");
$this->assertEquals(1, $this->reader->getCurrentPosition(), "CurPos与预计不符");
$this->readerWithCn->reset(); $this->readerWithCn->reset();
$this->assertEquals('中', $this->readerWithCn->getNextChar(), "不匹配"); $this->assertEquals('中', $this->readerWithCn->getNextChar(), "不匹配");
$this->assertEquals(1, $this->readerWithCn->getCurrentPosition(), "CurPos与预计不符");
} }
public function testGetCurrentToken() public function testGetCurrentToken()
{ {
$this->reader->reset(); $this->reader->reset();
$this->assertEquals('Ahhh', $this->reader->getCurrentToken(), "不匹配"); $this->assertEquals('Ahhh', $this->reader->getCurrentToken(), "不匹配");
$this->assertEquals(6, $this->reader->getNextPosition(), "NextPos与预计不符");
$this->readerWithCn->reset(); $this->readerWithCn->reset();
$this->assertEquals('中文', $this->readerWithCn->getCurrentToken(), "不匹配"); $this->assertEquals('中文', $this->readerWithCn->getCurrentToken(), "不匹配");
$this->assertEquals(4, $this->readerWithCn->getNextPosition(), "NextPos与预计不符");
} }
/** /**
* 移动至下一个Token
* @author Jerry Yan <792602257@qq.com> * @author Jerry Yan <792602257@qq.com>
* @date 2020/12/18 14:16 * @date 2020/12/18 14:16
* @depends testGetNextChar * @depends testGetNextChar
@ -47,8 +52,25 @@ class StringReaderTest extends TestCase
$this->reader->reset(); $this->reader->reset();
$this->reader->moveToNextToken(); $this->reader->moveToNextToken();
$this->assertEquals('This', $this->reader->getCurrentToken(), "不匹配"); $this->assertEquals('This', $this->reader->getCurrentToken(), "不匹配");
$this->assertEquals(7, $this->reader->getCurrentPosition(), "CurPos与预计不符");
$this->readerWithCn->reset(); $this->readerWithCn->reset();
$this->readerWithCn->moveToNextToken(); $this->readerWithCn->moveToNextToken();
$this->assertEquals('这是', $this->readerWithCn->getCurrentToken(), "不匹配"); $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不可以发生变化");
} }
} }