//Language: Perl


// tokens
Token=tnone
Token=tstring
Token=tcomment
Token=tident
Token=tinteger
Token=tfloat
Token=tresword
Token=tvariable
Token=tsymbol
Token=turl
Token=twhitespace


// states
State=snormal
State=sstring1
State=sstring2
State=sstring3
State=sstring4
State=scomment

//delims
Delimiters=;.,:'"{}[]()?!@#$%^&*-+=|\/

// reswords
snormal 'and'      snormal tresword
snormal 'cmp'      snormal tresword
snormal 'continue' snormal tresword
snormal 'do'       snormal tresword
snormal 'else'     snormal tresword
snormal 'elsif'    snormal tresword
snormal 'eq'       snormal tresword
snormal 'for'      snormal tresword
snormal 'foreach'  snormal tresword
snormal 'ge'       snormal tresword
snormal 'goto'     snormal tresword
snormal 'gt'       snormal tresword
snormal 'if'       snormal tresword
snormal 'last'     snormal tresword
snormal 'le'       snormal tresword
snormal 'lt'       snormal tresword
snormal 'my'       snormal tresword
snormal 'ne'       snormal tresword
snormal 'next'     snormal tresword
snormal 'not'      snormal tresword
snormal 'or'       snormal tresword
snormal 'package'  snormal tresword
snormal 'return'   snormal tresword
snormal 'require'  snormal tresword
snormal 'sub'      snormal tresword
snormal 'switch'   snormal tresword
snormal 'unless'   snormal tresword
snormal 'until'    snormal tresword
snormal 'use'      snormal tresword
snormal 'while'    snormal tresword
snormal 'xor'      snormal tresword

// numbers
snormal [0-9][0-9]*                            snormal  tinteger
snormal [1-9][0-9]*\.[0-9]*                    snormal  tfloat
snormal [1-9][0-9]*{\.[0-9]+}|e{[\+\-]}|[0-9]+ snormal  tfloat

//idents
snormal   [a-z_A-Z][a-z_A-Z0-9]*   snormal   tident
snormal   \$[a-z_A-Z0-9]*          snormal   tvariable
snormal   \$\#[a-z_A-Z0-9]*        snormal   tident

//white space
snormal #32*                      snormal    twhitespace

//strings
snormal    \"                     sstring1   tstring
sstring1   [^\"]*                 sstring1   tstring
sstring1   \"                     snormal    tstring
sstring1   \"\"                   sstring1   tstring
sstring1   \\                     sstring1   tstring
sstring1   \\\"                   sstring1   tstring
sstring1   $                      snormal    tstring
//
snormal    \'                     sstring2   tstring
sstring2   [^\']*                 sstring2   tstring
sstring2   \'                     snormal    tstring
sstring2   \'\'                   sstring2   tstring
sstring2   \\                     sstring2   tstring
sstring2   \\\'                   sstring2   tstring
sstring2   $                      snormal    tstring
//
snormal    \`                     sstring3   tstring
sstring3   [^\`]*                 sstring3   tstring
sstring3   \`                     snormal    tstring
sstring3   \`\`                   sstring3   tstring
sstring3   \\                     sstring3   tstring
sstring3   \\\`                   sstring3   tstring
sstring3   $                      snormal    tstring

//symbols  (must be before heredoc)
snormal  [&=<>()/?!,:;|\.\+\*\{\}\[\]\-]  snormal    tsymbol

//heredoc
snormal <<<EO[A-Z]$             sstring4   tstring
sstring4  .*$                   sstring4   tstring
sstring4  ^EO[A-Z];$            snormal    tstring
sstring4  ^EO[A-Z]$             snormal    tstring

//comments
snormal   \#                       scomment tcomment
scomment .*                        snormal  tcomment
scomment $                         snormal  tcomment
 
