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