You've already forked MyDSL
抽象
This commit is contained in:
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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不可以发生变化");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user