class Noir::PhpLexer

Overview

PhpLexer is a hand-rolled structural lexer for PHP source. It exists to replace the per-analyzer character state machines that every PHP analyzer re-implements (balanced-brace matching, statement-end scanning, string/ comment skip ranges) with a single shared pass that is:

The lexer masks every non-code region (inline HTML, strings, comments, heredoc/nowdoc bodies) into spaces in @masked while preserving newlines and overall length, so the structural helpers in Noir::MaskedLexer are plain depth counters over @masked with no string-state bookkeeping of their own.

Included Modules

Defined in:

minilexers/php_lexer.cr

Constructors

Instance Method Summary

Instance methods inherited from module Noir::MaskedLexer

in_code?(pos : Int32) : Bool in_code?, masked : Array(Char) masked, matching_delimiter(open_pos : Int32) : Int32 | Nil matching_delimiter, skip_ranges : Array(Range(Int32, Int32)) skip_ranges, statement_end(start_pos : Int32) : Int32 statement_end

Constructor Detail

def self.new(source : String, *, php_mode : Bool = false) #

source is a whole .php file by default, so lexing starts in HTML mode: nothing is code until the first <?php / <?=. Pass php_mode: true when source is a fragment already carved out of a PHP region (a closure body handed back for a recursive pass, say), which by construction has no opening tag of its own.


[View source]

Instance Method Detail

def expression_end(start_pos : Int32) : Int32 #

Index of the first top-level expression terminator (, ; or a closing ) ] } that would pop above the starting level) at or after start_pos. Mirrors find_arrow_expression_end.


[View source]
def tokens : Array(PhpToken) #

Lazily produce a flat token stream over the source: structural delimiters, ->/::/=> operators, identifiers, $variables, and one token per string/comment/heredoc span. This is the reusable miniparser surface for consumers that want to walk PHP structurally (e.g. following a Route::a(...)->b(...)->group(...) method chain).


[View source]