# "simple" variable inside string
syntax .php-strvar

state start
    char a-zA-Z_ strvar
    noeat END

state strvar
    char a-zA-Z_0-9 this
    noeat END

# Curly braces inside string
syntax .php-strcurly

state strvar
    char } END strvar
    eat this

# Common escapes inside double quotes and heredocs
syntax .php-esc

state special
    char x hex
    # 1-3 octal digits, \777 (0x1ff) overflows to 0xff
    char 0-7 oct1
    recolor string 1
    eat END

state hex special
    char 0-9a-fA-F hex2
    # "\xq" is not an error, it's literal
    recolor string 2
    noeat END

state hex2 special
    char 0-9a-fA-F END special
    # Single hex digit is ok
    noeat END

state oct1 special
    char 0-7 oct2
    noeat END

state oct2 special
    char 0-7 END special
    noeat END

# Common to <<<END and <<<"END"
syntax .php-heredoc-common

state bol string
    heredocend match
    noeat string

state string
    char "\n" bol
    char \\ esc
    char \$ .php-strvar:this strvar
    str '{$' .php-strcurly:this strvar
    eat this

state esc special
    # NOTE: \" is not special unlike in double quotes
    char 'nrtvf\$' string special
    noeat .php-esc:string

state match special
    char "\n" END
    str ";\n" END
    # Length clamped to bol
    recolor string 1000
    noeat string

# heredoc: <<<END
syntax .php-heredoc

state start special
    char "\n" .php-heredoc-common:END
    noeat END

# heredoc: <<<"END"
syntax .php-heredoc-dq

state start special
    str "\"\n" .php-heredoc-common:END
    noeat END

# nowdoc: <<<'END'
syntax .php-nowdoc

state start special
    str "'\n" bol
    noeat END

state bol string
    heredocend match
    noeat string

state string
    char "\n" bol
    eat this

state match special
    char "\n" END
    str ";\n" END
    # Length clamped to bol
    recolor string 1000
    noeat string

# Inside <? and ?>
syntax .php

state code
    char -b a-zA-Z_ word
    char \$ variable
    char \" dq
    char \' sq
    char 0 zero
    char 1-9 dec
    char . dot
    char ? qm
    str "//" cpp-comment
    str "/*" c-comment
    char # sh-comment
    str <<< heredoc
    eat this

state word code
    char -b a-zA-Z_0-9 this
    inlist keyword code
    inlist constant code
    inlist lang code
    noeat code

state variable
    char -b a-zA-Z_ variable2
    noeat code

state variable2 variable
    char -b a-zA-Z_0-9 this
    bufis this this-keyword
    noeat code

state this-keyword
    recolor this 5
    noeat code

state dq string
    char \" code string
    char \\ dqesc
    char \$ .php-strvar:this strvar
    str '{$' .php-strcurly:this strvar
    eat this

state dqesc special
    char 'nrtvf\$"' dq special
    noeat .php-esc:dq

state sq string
    char \' code string
    char \\ sqesc
    eat this

state sqesc string
    # Not \ or '
    char -n "\\'" sq
    recolor special 1
    eat sq special

state zero numeric
    char xX hex
    char 0-7 oct
    char . float
    noeat check-suffix

state oct numeric
    char 0-7 this
    noeat check-suffix

state dec numeric
    char 0-9 this
    char eE exp
    char . float
    noeat check-suffix

state hex numeric
    char 0-9a-fA-F this
    noeat check-suffix

state check-suffix error
    char a-zA-Z0-9_ this
    noeat code

state dot numeric
    char 0-9 float
    recolor code 1
    noeat code

state float numeric
    char 0-9 this
    char eE exp
    noeat check-suffix

state exp numeric
    char +- exp-digit
    char 0-9 exp-digit
    noeat check-suffix

state exp-digit numeric
    char 0-9 this
    noeat check-suffix

state qm tag
    char > END tag
    recolor code 1
    noeat code

state cpp-comment comment
    char "\n" code
    eat this

state c-comment comment
    str "*/" code comment
    eat this

state sh-comment comment
    char "\n" code
    eat this

state heredoc special
    char -b a-zA-Z_ heredoc-plain
    char \" heredoc-dq-start
    char \' nowdoc-start
    noeat code

state heredoc-plain special
    char -b a-zA-Z0-9_ this
    heredocbegin .php-heredoc code

state heredoc-dq-start special
    char -b a-zA-Z_ heredoc-dq
    noeat code

state heredoc-dq special
    char -b a-zA-Z0-9_ this
    heredocbegin .php-heredoc-dq code

state nowdoc-start special
    char -b a-zA-Z_ nowdoc
    noeat code

state nowdoc special
    char -b a-zA-Z0-9_ this
    heredocbegin .php-nowdoc code

list keyword \
    abstract and array as break case catch cfunction class clone \
    const continue declare default do else elseif enddeclare \
    endfor endforeach endif endswitch endwhile extends final for \
    foreach function global goto if implements interface \
    instanceof namespace new old_function or private protected \
    public static switch throw try use var while xor self parent

list -i constant \
    __CLASS__ __DIR__ __FILE__ __FUNCTION__ __METHOD__ __NAMESPACE__ \
    false null true

# Language constructs
list lang \
    die echo empty exit eval include include_once isset list require \
    require_once return print unset

syntax php

state code
    char < lab
    eat this

state lab tag
    char ? tag-php
    recolor code 1
    noeat code

state tag-php tag
    str "php" tag-ver
    noeat .php:code

state tag-ver tag
    char 3-5 .php:code tag
    noeat .php:code

default special tag
default keyword lang
default special strvar
default variable this
