forked from golang/hotime
223 lines
3.9 KiB
Perl
223 lines
3.9 KiB
Perl
#!/usr/bin/env perl
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
my (%token, @order, @keywords);
|
|
|
|
{
|
|
my $keywords;
|
|
my @const;
|
|
push @const, <<_END_;
|
|
package token
|
|
|
|
const(
|
|
_ Token = iota
|
|
_END_
|
|
|
|
for (split m/\n/, <<_END_) {
|
|
ILLEGAL
|
|
EOF
|
|
COMMENT
|
|
KEYWORD
|
|
|
|
STRING
|
|
BOOLEAN
|
|
NULL
|
|
NUMBER
|
|
IDENTIFIER
|
|
|
|
PLUS +
|
|
MINUS -
|
|
MULTIPLY *
|
|
SLASH /
|
|
REMAINDER %
|
|
|
|
AND &
|
|
OR |
|
|
EXCLUSIVE_OR ^
|
|
SHIFT_LEFT <<
|
|
SHIFT_RIGHT >>
|
|
UNSIGNED_SHIFT_RIGHT >>>
|
|
AND_NOT &^
|
|
|
|
ADD_ASSIGN +=
|
|
SUBTRACT_ASSIGN -=
|
|
MULTIPLY_ASSIGN *=
|
|
QUOTIENT_ASSIGN /=
|
|
REMAINDER_ASSIGN %=
|
|
|
|
AND_ASSIGN &=
|
|
OR_ASSIGN |=
|
|
EXCLUSIVE_OR_ASSIGN ^=
|
|
SHIFT_LEFT_ASSIGN <<=
|
|
SHIFT_RIGHT_ASSIGN >>=
|
|
UNSIGNED_SHIFT_RIGHT_ASSIGN >>>=
|
|
AND_NOT_ASSIGN &^=
|
|
|
|
LOGICAL_AND &&
|
|
LOGICAL_OR ||
|
|
INCREMENT ++
|
|
DECREMENT --
|
|
|
|
EQUAL ==
|
|
STRICT_EQUAL ===
|
|
LESS <
|
|
GREATER >
|
|
ASSIGN =
|
|
NOT !
|
|
|
|
BITWISE_NOT ~
|
|
|
|
NOT_EQUAL !=
|
|
STRICT_NOT_EQUAL !==
|
|
LESS_OR_EQUAL <=
|
|
GREATER_OR_EQUAL <=
|
|
|
|
LEFT_PARENTHESIS (
|
|
LEFT_BRACKET [
|
|
LEFT_BRACE {
|
|
COMMA ,
|
|
PERIOD .
|
|
|
|
RIGHT_PARENTHESIS )
|
|
RIGHT_BRACKET ]
|
|
RIGHT_BRACE }
|
|
SEMICOLON ;
|
|
COLON :
|
|
QUESTION_MARK ?
|
|
|
|
firstKeyword
|
|
IF
|
|
IN
|
|
DO
|
|
|
|
VAR
|
|
FOR
|
|
NEW
|
|
TRY
|
|
|
|
THIS
|
|
ELSE
|
|
CASE
|
|
VOID
|
|
WITH
|
|
|
|
WHILE
|
|
BREAK
|
|
CATCH
|
|
THROW
|
|
|
|
RETURN
|
|
TYPEOF
|
|
DELETE
|
|
SWITCH
|
|
|
|
DEFAULT
|
|
FINALLY
|
|
|
|
FUNCTION
|
|
CONTINUE
|
|
DEBUGGER
|
|
|
|
INSTANCEOF
|
|
lastKeyword
|
|
_END_
|
|
chomp;
|
|
|
|
next if m/^\s*#/;
|
|
|
|
my ($name, $symbol) = m/(\w+)\s*(\S+)?/;
|
|
|
|
if (defined $symbol) {
|
|
push @order, $name;
|
|
push @const, "$name // $symbol";
|
|
$token{$name} = $symbol;
|
|
} elsif (defined $name) {
|
|
$keywords ||= $name eq 'firstKeyword';
|
|
|
|
push @const, $name;
|
|
#$const[-1] .= " Token = iota" if 2 == @const;
|
|
if ($name =~ m/^([A-Z]+)/) {
|
|
push @keywords, $name if $keywords;
|
|
push @order, $name;
|
|
if ($token{SEMICOLON}) {
|
|
$token{$name} = lc $1;
|
|
} else {
|
|
$token{$name} = $name;
|
|
}
|
|
}
|
|
} else {
|
|
push @const, "";
|
|
}
|
|
|
|
}
|
|
push @const, ")";
|
|
print join "\n", @const, "";
|
|
}
|
|
|
|
{
|
|
print <<_END_;
|
|
|
|
var token2string = [...]string{
|
|
_END_
|
|
for my $name (@order) {
|
|
print "$name: \"$token{$name}\",\n";
|
|
}
|
|
print <<_END_;
|
|
}
|
|
_END_
|
|
|
|
print <<_END_;
|
|
|
|
var keywordTable = map[string]_keyword{
|
|
_END_
|
|
for my $name (@keywords) {
|
|
print <<_END_
|
|
"@{[ lc $name ]}": _keyword{
|
|
token: $name,
|
|
},
|
|
_END_
|
|
}
|
|
|
|
for my $name (qw/
|
|
const
|
|
class
|
|
enum
|
|
export
|
|
extends
|
|
import
|
|
super
|
|
/) {
|
|
print <<_END_
|
|
"$name": _keyword{
|
|
token: KEYWORD,
|
|
futureKeyword: true,
|
|
},
|
|
_END_
|
|
}
|
|
|
|
for my $name (qw/
|
|
implements
|
|
interface
|
|
let
|
|
package
|
|
private
|
|
protected
|
|
public
|
|
static
|
|
/) {
|
|
print <<_END_
|
|
"$name": _keyword{
|
|
token: KEYWORD,
|
|
futureKeyword: true,
|
|
strict: true,
|
|
},
|
|
_END_
|
|
}
|
|
|
|
print <<_END_;
|
|
}
|
|
_END_
|
|
}
|