Main.cta

main:
    is:
        :php_open_tag
php_open_tag:
    if_unstarted:
        buffer.ends_with <?php
        buffer.clear
        :php_code
    if_started:
        buffer.ends_with ?>
        buffer.clear
php_stop:
    if_unstarted:
        buffer.ends_with ?>
        pop directive_stack
        pop directive_stack
        rewind 2
        buffer.clear
php_code:
    if_unstarted:
        buffer.rewind 1
        :word
        :operation
        :whitespace
        :comment
        docblock:docblock_open
        :string
        :php_stop
    if_started:
        debug.die php_code.stop should never execute, because the stopping is handled by the \
word:
    if_unstarted:
        buffer.match /^[a-zA-Z0-9\_\\]$/
    if_started:
        buffer.match /[^a-zA-Z0-9\_\\]$/
        buffer.rewind 1
        :word_main
        buffer.clear
operation:
    if_unstarted:
        this.operation_match
        match /./
        this.handleOperation
        buffer.clear
        stop
whitespace:
    if_unstarted:
        match /^\s$/i
        lexer.unsetPrevious whitespace
    if_started:
        match /[^\s]$/i
        rewind 1
        this.handleWhitespace
        buffer.clear
comment:
    if_unstarted:
        buffer.match /(\\/\\/|\#)/
        buffer.clear
    if_started:
        match /(\r\n|\n)$/
        this.handleComment
        buffer.clear
string:
    is:
        :string_single
        :string_double
        :heredoc