use strict;
my $sql = <<'--SQL--';
select case
when a=b then 'c'
else 'd'
end "tough_one",
e as "even tougher"
from mytable
--SQL--
use HOP::Lexer 'make_lexer';
my @sql = $sql;
my $lexer = make_lexer(
sub { shift @sql }, # iterator
[ WORD => qr/\w+/i ],
[ DQWORD => qr/"\w+"/ ],
[ DQUOTED => qr/"[^"]+"/ ],
[ QUOTED => qr/'[^']*'/ ],
[ COMMA => qr/,/ ],
[ SPACE => qr/\s+/, sub {} ],
);
# parse
my @out;
push @out, $_ while $_ = $lexer->();
# Data::Dump the output (elaborated in order to produce compact results)
use Data::Dumper;
$Data::Dumper::Indent = 0;
$Data::Dumper::Terse = 1;
($\, $,) = ("\n", ",\n");
print map { Dumper $_ } @out;
####
['WORD','select'],
['WORD','case'],
['WORD','when'],
['WORD','a'],
'=',
['WORD','b'],
['WORD','then'],
'\'',
['WORD','c'],
'\'',
['WORD','else'],
'\'',
['WORD','d'],
'\'',
['WORD','end'],
'"',
['WORD','tough_one'],
'"',
['COMMA',','],
['WORD','e'],
['WORD','as'],
'"',
['WORD','even'],
['WORD','tougher'],
'"',
['WORD','from'],
['WORD','mytable']
####
['WORD','select'],
['WORD','case'],
['WORD','when'],
['WORD','a'],
'=',
['WORD','b'],
['WORD','then'],
['QUOTED', '\'c\''],
['WORD','else'],
['QUOTED','\'d\''],
['WORD','end'],
['DQWORD','"tough_one"'],
['COMMA',','],
['WORD','e'],
['WORD','as'],
['DQUOTED','"even tougher"'],
['WORD','from'],
['WORD','mytable']