acf
This commit is contained in:
215
plugins/system/nrframework/NRFramework/Parser/Lexer.php
Normal file
215
plugins/system/nrframework/NRFramework/Parser/Lexer.php
Normal file
@ -0,0 +1,215 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author Tassos.gr <info@tassos.gr>
|
||||
* @link https://www.tassos.gr
|
||||
* @copyright Copyright © 2024 Tassos All Rights Reserved
|
||||
* @license GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later
|
||||
*/
|
||||
|
||||
namespace NRFramework\Parser;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use NRFramework\Parser\Tokens;
|
||||
|
||||
/**
|
||||
* Lexer base class
|
||||
*
|
||||
* TODO: Rename to Tokenizer??
|
||||
*/
|
||||
abstract class Lexer
|
||||
{
|
||||
/**
|
||||
* EOF character
|
||||
*/
|
||||
const EOF = -1;
|
||||
|
||||
/**
|
||||
* Tokens instance
|
||||
*
|
||||
* @var NRFramework\Parser\Tokens
|
||||
*/
|
||||
protected $tokens = null; // Tokens instance
|
||||
|
||||
/**
|
||||
* Input string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $input;
|
||||
|
||||
/**
|
||||
* Input string length
|
||||
*/
|
||||
protected $length;
|
||||
|
||||
/**
|
||||
* The index of the current character
|
||||
* in the input string
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $index = 0;
|
||||
|
||||
/**
|
||||
* Current character in input string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $cur;
|
||||
|
||||
/**
|
||||
* A Mark(position) inside the input string.
|
||||
* Used when matching ahead of the 'current' character
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $mark = 0;
|
||||
|
||||
/**
|
||||
* Holds the Lexer's state
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* Lexer constructor
|
||||
*
|
||||
* @param string $input
|
||||
*/
|
||||
public function __construct($input)
|
||||
{
|
||||
$this->input = $input;
|
||||
$this->length = strlen($input);
|
||||
$this->cur = $this->length >= 1 ? $this->input[0] : Lexer::EOF;
|
||||
$this->tokens = new Tokens();
|
||||
|
||||
// inititalize state
|
||||
$this->state = new \StdClass();
|
||||
$this->state->skip_whitespace = true;
|
||||
$this->state->tokenize_content = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next token from the input string.
|
||||
*
|
||||
* @return NRFramework\Parser\Token
|
||||
*/
|
||||
abstract function nextToken();
|
||||
|
||||
/**
|
||||
* Moves n characters ahead in the input string.
|
||||
* Returns all n characters.
|
||||
* Detects "end of file".
|
||||
*
|
||||
* @param integer $n Number of characters to advance
|
||||
* @return string The n previous characters
|
||||
*/
|
||||
public function consume($n = 1)
|
||||
{
|
||||
$prev = '';
|
||||
for ($i=0; $i < $n; $i++)
|
||||
{
|
||||
$prev .= $this->cur;
|
||||
if ( ($this->index + 1) >= $this->length)
|
||||
{
|
||||
$this->cur = Lexer::EOF;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->index++;
|
||||
$this->cur = $this->input[$this->index];
|
||||
}
|
||||
}
|
||||
|
||||
return $prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the skip_whitespce state
|
||||
*
|
||||
* @param boolean $skip
|
||||
* @return void
|
||||
*/
|
||||
public function setSkipWhitespaceState($skip = true)
|
||||
{
|
||||
$this->state->skip_whitespace = $skip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tokenize_content state
|
||||
*
|
||||
* @param bool
|
||||
* @return void
|
||||
*/
|
||||
public function setTokenizeContentState($state = true)
|
||||
{
|
||||
$this->state->tokenize_content = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tokenize_content state
|
||||
*
|
||||
* @param bool
|
||||
* @return bool
|
||||
*/
|
||||
public function getTokenizeContentState()
|
||||
{
|
||||
return $this->state->tokenize_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the current index
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function mark()
|
||||
{
|
||||
$this->mark = $this->index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset index to previously marked position (or at the start of the stream if not marked)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->index = $this->mark;
|
||||
$this->cur = $this->input[$this->index];
|
||||
$this->mark = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the token types array from the Tokens instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getTokensTypes()
|
||||
{
|
||||
return $this->tokens->getTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current position in the input stream
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getStreamPosition()
|
||||
{
|
||||
return $this->index;
|
||||
}
|
||||
|
||||
/**
|
||||
* whitespace : (' '|'\t'|'\n'|'\r')
|
||||
* Ignores any whitespace while advancing
|
||||
* @return null
|
||||
*/
|
||||
protected function whitespace()
|
||||
{
|
||||
while (preg_match('/\s+/', $this->cur)) $this->consume();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user