202 lines
5.3 KiB
Perl
Executable File
202 lines
5.3 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
#
|
|
|
|
package S2::TokenStringLiteral;
|
|
|
|
use strict;
|
|
use S2::Token;
|
|
use vars qw($VERSION @ISA);
|
|
|
|
$VERSION = '1.0';
|
|
@ISA = qw(S2::Token);
|
|
|
|
# int quotesLeft;
|
|
# int quotesRight;
|
|
# String text;
|
|
# String source;
|
|
|
|
sub new
|
|
{
|
|
my $class = shift;
|
|
my ($text, $source, $ql, $qr);
|
|
if (@_ == 1) {
|
|
$text = shift;
|
|
($ql, $qr) = (1, 1);
|
|
$source = $text;
|
|
} elsif (@_ == 3) {
|
|
($text, $ql, $qr) = @_;
|
|
$source = $text;
|
|
} elsif (@_ == 4) {
|
|
($text, $source, $ql, $qr) = @_;
|
|
unless (defined $text) {
|
|
$text = $source;
|
|
$text =~ s/\\n/\n/g;
|
|
$text =~ s/\\\"/\"/g;
|
|
$text =~ s/\\\$/\$/g;
|
|
$text =~ s/\\\\/\\/g;
|
|
}
|
|
} else {
|
|
die;
|
|
}
|
|
|
|
bless {
|
|
'text' => $text,
|
|
'chars' => $source,
|
|
'quotesLeft' => $ql,
|
|
'quotesRight' => $qr,
|
|
}, $class;
|
|
}
|
|
|
|
sub getQuotesLeft { shift->{'quotesLeft'}; }
|
|
sub getQuotesRight { shift->{'quotesRight'}; }
|
|
sub setQuotesLeft { my $this = shift; $this->{'quotesLeft'} = shift; }
|
|
sub setQuotesRight { my $this = shift; $this->{'quotesRight'} = shift; }
|
|
|
|
sub clone {
|
|
my $this = shift;
|
|
return S2::TokenStringLiteral->new($this->{'text'},
|
|
$this->{'chars'},
|
|
$this->{'quotesLeft'},
|
|
$this->{'quotesRight'});
|
|
}
|
|
|
|
sub getString
|
|
{
|
|
shift->{'text'};
|
|
}
|
|
|
|
sub toString
|
|
{
|
|
my $this = shift;
|
|
my $buf = "[TokenStringLiteral] = ";
|
|
if ($this->{'quotesLeft'} == 0) { $buf .= "("; }
|
|
elsif ($this->{'quotesLeft'} == 1) { $buf .= "<"; }
|
|
elsif ($this->{'quotesLeft'} == 3) { $buf .= "<<"; }
|
|
else { die; }
|
|
$buf .= $this->{'text'};
|
|
if ($this->{'quotesRight'} == 0) { $buf .= ")"; }
|
|
elsif ($this->{'quotesRight'} == 1) { $buf .= ">"; }
|
|
elsif ($this->{'quotesRight'} == 3) { $buf .= ">>"; }
|
|
else { die; }
|
|
return $buf;
|
|
}
|
|
|
|
sub asHTML
|
|
{
|
|
my ($this, $o) = @_;
|
|
my $ret;
|
|
$ret .= makeQuotes($this->{'quotesLeft'});
|
|
$ret .= $this->{'chars'};
|
|
$ret .= makeQuotes($this->{'quotesRight'});
|
|
$o->write("<span class=\"s\">" . S2::BackendHTML::quoteHTML($ret) . "</span>");
|
|
}
|
|
|
|
sub scan
|
|
{
|
|
my ($class, $t) = @_;
|
|
|
|
my $inTriple = 0;
|
|
my $continued = 0;
|
|
my $pos = $t->getPos();
|
|
|
|
if ($t->{'inString'} == 0) {
|
|
# see if this is a triple quoted string,
|
|
# like python. if so, don't need to escape quotes
|
|
$t->getRealChar(); # 1
|
|
if ($t->peekChar() eq '"') {
|
|
$t->getChar(); # 2
|
|
if ($t->peekChar() eq '"') {
|
|
$t->getChar(); # 3
|
|
$inTriple = 1;
|
|
} else {
|
|
$t->{'inString'} = 0;
|
|
return S2::TokenStringLiteral->new("", 1, 1);
|
|
}
|
|
}
|
|
} elsif ($t->{'inString'} == 3) {
|
|
$continued = 1;
|
|
$inTriple = 1;
|
|
} elsif ($t->{'inString'} == 1) {
|
|
$continued = 1;
|
|
}
|
|
|
|
my $tbuf; # text buffer (escaped)
|
|
my $sbuf; # source buffer
|
|
|
|
while (1) {
|
|
my $peekchar = $t->peekChar();
|
|
if (! defined $peekchar) {
|
|
die "Run-away string. Check for unbalanced quotes on string literals.\n";
|
|
} elsif ($peekchar eq '"') {
|
|
if (! $inTriple) {
|
|
$t->getChar();
|
|
$t->{'inString'} = 0;
|
|
return S2::TokenStringLiteral->new($tbuf, $sbuf, $continued ? 0 : 1, 1);
|
|
} else {
|
|
$t->getChar(); # 1
|
|
if ($t->peekChar() eq '"') {
|
|
$t->getChar(); # 2
|
|
if ($t->peekChar() eq '"') {
|
|
$t->getChar(); # 3
|
|
$t->{'inString'} = 0;
|
|
return S2::TokenStringLiteral->new($tbuf, $sbuf, $continued ? 0 : 3, 3);
|
|
} else {
|
|
$tbuf .= '""';
|
|
$sbuf .= '""';
|
|
}
|
|
} else {
|
|
$tbuf .= '"';
|
|
$sbuf .= '"';
|
|
}
|
|
}
|
|
} else {
|
|
if ($t->peekChar() eq '$') {
|
|
$t->{'inString'} = $inTriple ? 3 : 1;
|
|
return S2::TokenStringLiteral->new($tbuf, $sbuf,
|
|
$continued ? 0 : ($inTriple ? 3 : 1),
|
|
0);
|
|
}
|
|
|
|
if ($t->peekChar() eq "\\") {
|
|
$sbuf .= $t->getRealChar(); # skip the backslash. next thing will be literal.
|
|
$sbuf .= $t->peekChar();
|
|
if ($t->peekChar() eq 'n') {
|
|
$t->forceNextChar("\n");
|
|
}
|
|
$tbuf .= $t->getRealChar();
|
|
} else {
|
|
my $c = $t->getRealChar();
|
|
$tbuf .= $c;
|
|
$sbuf .= $c;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
sub asS2
|
|
{
|
|
my ($this, $o) = @_;
|
|
$o->write(makesQuote($this->{'quotesLeft'}));
|
|
$o->write(S2::Backend::quoteStringInner($this->{'text'}));
|
|
$o->write(makesQuote($this->{'quotesRight'}));
|
|
}
|
|
|
|
sub asPerl
|
|
{
|
|
my ($this, $bp, $o) = @_;
|
|
$o->write($bp->quoteString($this->{'text'}));
|
|
}
|
|
|
|
sub makeQuotes
|
|
{
|
|
my $i = shift;
|
|
return "" if $i == 0;
|
|
return "\"" if $i == 1;
|
|
return "\"\"\"" if $i == 3;
|
|
return "XXX";
|
|
}
|
|
|
|
|
|
1;
|
|
|