#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TokenKind {
My,
Our,
Local,
State,
Sub,
If,
Elsif,
Else,
Unless,
While,
Until,
For,
Foreach,
Return,
Package,
Use,
No,
Begin,
End,
Check,
Init,
Unitcheck,
Eval,
Do,
Given,
When,
Default,
Try,
Catch,
Finally,
Continue,
Next,
Last,
Redo,
Goto,
Class,
Method,
Field,
Format,
Undef,
Defer,
Assign,
Plus,
Minus,
Star,
Slash,
Percent,
Power,
LeftShift,
RightShift,
BitwiseAnd,
BitwiseOr,
BitwiseXor,
BitwiseNot,
PlusAssign,
MinusAssign,
StarAssign,
SlashAssign,
PercentAssign,
DotAssign,
AndAssign,
OrAssign,
XorAssign,
PowerAssign,
LeftShiftAssign,
RightShiftAssign,
LogicalAndAssign,
LogicalOrAssign,
DefinedOrAssign,
Equal,
NotEqual,
Match,
NotMatch,
SmartMatch,
Less,
Greater,
LessEqual,
GreaterEqual,
Spaceship,
StringCompare,
And,
Or,
Not,
DefinedOr,
WordAnd,
WordOr,
WordNot,
WordXor,
Arrow,
FatArrow,
Dot,
Range,
Ellipsis,
Increment,
Decrement,
DoubleColon,
Question,
Colon,
Backslash,
LeftParen,
RightParen,
LeftBrace,
RightBrace,
LeftBracket,
RightBracket,
Semicolon,
Comma,
Number,
String,
Regex,
Substitution,
Transliteration,
QuoteSingle,
QuoteDouble,
QuoteWords,
QuoteCommand,
HeredocStart,
HeredocBody,
FormatBody,
DataMarker,
DataBody,
VString,
UnknownRest,
HeredocDepthLimit,
Identifier,
ScalarSigil,
ArraySigil,
HashSigil,
SubSigil,
GlobSigil,
Eof,
Unknown,
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TokenCategory {
Keyword,
Operator,
Delimiter,
Literal,
Identifier,
Special,
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct TokenKindMetadata {
pub category: TokenCategory,
pub display_name: &'static str,
}
pub const KEYWORD_SPELLINGS: &[(&str, TokenKind)] = &[
("my", TokenKind::My),
("our", TokenKind::Our),
("local", TokenKind::Local),
("state", TokenKind::State),
("sub", TokenKind::Sub),
("if", TokenKind::If),
("elsif", TokenKind::Elsif),
("else", TokenKind::Else),
("unless", TokenKind::Unless),
("while", TokenKind::While),
("until", TokenKind::Until),
("for", TokenKind::For),
("foreach", TokenKind::Foreach),
("return", TokenKind::Return),
("package", TokenKind::Package),
("use", TokenKind::Use),
("no", TokenKind::No),
("BEGIN", TokenKind::Begin),
("END", TokenKind::End),
("CHECK", TokenKind::Check),
("INIT", TokenKind::Init),
("UNITCHECK", TokenKind::Unitcheck),
("eval", TokenKind::Eval),
("do", TokenKind::Do),
("given", TokenKind::Given),
("when", TokenKind::When),
("default", TokenKind::Default),
("try", TokenKind::Try),
("catch", TokenKind::Catch),
("finally", TokenKind::Finally),
("continue", TokenKind::Continue),
("next", TokenKind::Next),
("last", TokenKind::Last),
("redo", TokenKind::Redo),
("goto", TokenKind::Goto),
("class", TokenKind::Class),
("method", TokenKind::Method),
("field", TokenKind::Field),
("format", TokenKind::Format),
("undef", TokenKind::Undef),
("defer", TokenKind::Defer),
("and", TokenKind::WordAnd),
("or", TokenKind::WordOr),
("not", TokenKind::WordNot),
("xor", TokenKind::WordXor),
("cmp", TokenKind::StringCompare),
];
pub const OPERATOR_SPELLINGS: &[(&str, TokenKind)] = &[
("=", TokenKind::Assign),
("+", TokenKind::Plus),
("-", TokenKind::Minus),
("*", TokenKind::Star),
("/", TokenKind::Slash),
("%", TokenKind::Percent),
("**", TokenKind::Power),
("<<", TokenKind::LeftShift),
(">>", TokenKind::RightShift),
("&", TokenKind::BitwiseAnd),
("|", TokenKind::BitwiseOr),
("^", TokenKind::BitwiseXor),
("~", TokenKind::BitwiseNot),
("+=", TokenKind::PlusAssign),
("-=", TokenKind::MinusAssign),
("*=", TokenKind::StarAssign),
("/=", TokenKind::SlashAssign),
("%=", TokenKind::PercentAssign),
(".=", TokenKind::DotAssign),
("&=", TokenKind::AndAssign),
("|=", TokenKind::OrAssign),
("^=", TokenKind::XorAssign),
("**=", TokenKind::PowerAssign),
("<<=", TokenKind::LeftShiftAssign),
(">>=", TokenKind::RightShiftAssign),
("&&=", TokenKind::LogicalAndAssign),
("||=", TokenKind::LogicalOrAssign),
("//=", TokenKind::DefinedOrAssign),
("==", TokenKind::Equal),
("!=", TokenKind::NotEqual),
("=~", TokenKind::Match),
("!~", TokenKind::NotMatch),
("~~", TokenKind::SmartMatch),
("<", TokenKind::Less),
(">", TokenKind::Greater),
("<=", TokenKind::LessEqual),
(">=", TokenKind::GreaterEqual),
("<=>", TokenKind::Spaceship),
("&&", TokenKind::And),
("||", TokenKind::Or),
("!", TokenKind::Not),
("//", TokenKind::DefinedOr),
("->", TokenKind::Arrow),
("=>", TokenKind::FatArrow),
(".", TokenKind::Dot),
("..", TokenKind::Range),
("...", TokenKind::Ellipsis),
("++", TokenKind::Increment),
("--", TokenKind::Decrement),
("::", TokenKind::DoubleColon),
("?", TokenKind::Question),
(":", TokenKind::Colon),
("\\", TokenKind::Backslash),
];
pub const DELIMITER_SPELLINGS: &[(&str, TokenKind)] = &[
("(", TokenKind::LeftParen),
(")", TokenKind::RightParen),
("{", TokenKind::LeftBrace),
("}", TokenKind::RightBrace),
("[", TokenKind::LeftBracket),
("]", TokenKind::RightBracket),
(";", TokenKind::Semicolon),
(",", TokenKind::Comma),
];
pub const SIGIL_SPELLINGS: &[(&str, TokenKind)] = &[
("$", TokenKind::ScalarSigil),
("@", TokenKind::ArraySigil),
("%", TokenKind::HashSigil),
("&", TokenKind::SubSigil),
("*", TokenKind::GlobSigil),
];
impl TokenKind {
pub const fn all() -> &'static [TokenKind] {
&TOKEN_KIND_ALL
}
pub const fn metadata_count() -> usize {
TOKEN_KIND_ALL.len()
}
pub fn metadata(self) -> TokenKindMetadata {
TokenKindMetadata { category: self.category(), display_name: self.display_name() }
}
pub const fn category(self) -> TokenCategory {
match self {
TokenKind::My
| TokenKind::Our
| TokenKind::Local
| TokenKind::State
| TokenKind::Sub
| TokenKind::If
| TokenKind::Elsif
| TokenKind::Else
| TokenKind::Unless
| TokenKind::While
| TokenKind::Until
| TokenKind::For
| TokenKind::Foreach
| TokenKind::Return
| TokenKind::Package
| TokenKind::Use
| TokenKind::No
| TokenKind::Begin
| TokenKind::End
| TokenKind::Check
| TokenKind::Init
| TokenKind::Unitcheck
| TokenKind::Eval
| TokenKind::Do
| TokenKind::Given
| TokenKind::When
| TokenKind::Default
| TokenKind::Try
| TokenKind::Catch
| TokenKind::Finally
| TokenKind::Continue
| TokenKind::Next
| TokenKind::Last
| TokenKind::Redo
| TokenKind::Goto
| TokenKind::Class
| TokenKind::Method
| TokenKind::Field
| TokenKind::Format
| TokenKind::Undef
| TokenKind::Defer => TokenCategory::Keyword,
TokenKind::Assign
| TokenKind::Plus
| TokenKind::Minus
| TokenKind::Star
| TokenKind::Slash
| TokenKind::Percent
| TokenKind::Power
| TokenKind::LeftShift
| TokenKind::RightShift
| TokenKind::BitwiseAnd
| TokenKind::BitwiseOr
| TokenKind::BitwiseXor
| TokenKind::BitwiseNot
| TokenKind::PlusAssign
| TokenKind::MinusAssign
| TokenKind::StarAssign
| TokenKind::SlashAssign
| TokenKind::PercentAssign
| TokenKind::DotAssign
| TokenKind::AndAssign
| TokenKind::OrAssign
| TokenKind::XorAssign
| TokenKind::PowerAssign
| TokenKind::LeftShiftAssign
| TokenKind::RightShiftAssign
| TokenKind::LogicalAndAssign
| TokenKind::LogicalOrAssign
| TokenKind::DefinedOrAssign
| TokenKind::Equal
| TokenKind::NotEqual
| TokenKind::Match
| TokenKind::NotMatch
| TokenKind::SmartMatch
| TokenKind::Less
| TokenKind::Greater
| TokenKind::LessEqual
| TokenKind::GreaterEqual
| TokenKind::Spaceship
| TokenKind::StringCompare
| TokenKind::And
| TokenKind::Or
| TokenKind::Not
| TokenKind::DefinedOr
| TokenKind::WordAnd
| TokenKind::WordOr
| TokenKind::WordNot
| TokenKind::WordXor
| TokenKind::Arrow
| TokenKind::FatArrow
| TokenKind::Dot
| TokenKind::Range
| TokenKind::Ellipsis
| TokenKind::Increment
| TokenKind::Decrement
| TokenKind::DoubleColon
| TokenKind::Question
| TokenKind::Colon
| TokenKind::Backslash => TokenCategory::Operator,
TokenKind::LeftParen
| TokenKind::RightParen
| TokenKind::LeftBrace
| TokenKind::RightBrace
| TokenKind::LeftBracket
| TokenKind::RightBracket
| TokenKind::Semicolon
| TokenKind::Comma => TokenCategory::Delimiter,
TokenKind::Number
| TokenKind::String
| TokenKind::Regex
| TokenKind::Substitution
| TokenKind::Transliteration
| TokenKind::QuoteSingle
| TokenKind::QuoteDouble
| TokenKind::QuoteWords
| TokenKind::QuoteCommand
| TokenKind::HeredocStart
| TokenKind::HeredocBody
| TokenKind::FormatBody
| TokenKind::DataMarker
| TokenKind::DataBody
| TokenKind::VString
| TokenKind::UnknownRest
| TokenKind::HeredocDepthLimit => TokenCategory::Literal,
TokenKind::Identifier
| TokenKind::ScalarSigil
| TokenKind::ArraySigil
| TokenKind::HashSigil
| TokenKind::SubSigil
| TokenKind::GlobSigil => TokenCategory::Identifier,
TokenKind::Eof | TokenKind::Unknown => TokenCategory::Special,
}
}
pub const fn is_keyword(self) -> bool {
matches!(self.category(), TokenCategory::Keyword)
}
pub const fn is_operator(self) -> bool {
matches!(self.category(), TokenCategory::Operator)
}
pub const fn is_literal(self) -> bool {
matches!(self.category(), TokenCategory::Literal)
}
pub const fn is_delimiter(self) -> bool {
matches!(self.category(), TokenCategory::Delimiter)
}
pub const fn is_identifier(self) -> bool {
matches!(self.category(), TokenCategory::Identifier)
}
pub const fn is_special(self) -> bool {
matches!(self.category(), TokenCategory::Special)
}
#[inline]
pub fn is_assignment_operator(self) -> bool {
matches!(
self,
TokenKind::Assign
| TokenKind::PlusAssign
| TokenKind::MinusAssign
| TokenKind::StarAssign
| TokenKind::SlashAssign
| TokenKind::PercentAssign
| TokenKind::DotAssign
| TokenKind::AndAssign
| TokenKind::OrAssign
| TokenKind::XorAssign
| TokenKind::PowerAssign
| TokenKind::LeftShiftAssign
| TokenKind::RightShiftAssign
| TokenKind::LogicalAndAssign
| TokenKind::LogicalOrAssign
| TokenKind::DefinedOrAssign
)
}
#[inline]
pub fn is_comparison_operator(self) -> bool {
matches!(
self,
TokenKind::Equal
| TokenKind::NotEqual
| TokenKind::Less
| TokenKind::Greater
| TokenKind::LessEqual
| TokenKind::GreaterEqual
| TokenKind::Spaceship
| TokenKind::StringCompare
| TokenKind::Match
| TokenKind::NotMatch
| TokenKind::SmartMatch
)
}
#[inline]
pub fn is_logical_operator(self) -> bool {
matches!(
self,
TokenKind::And
| TokenKind::Or
| TokenKind::Not
| TokenKind::DefinedOr
| TokenKind::WordAnd
| TokenKind::WordOr
| TokenKind::WordNot
| TokenKind::WordXor
)
}
#[inline]
pub fn is_word_operator(self) -> bool {
matches!(
self,
TokenKind::StringCompare
| TokenKind::WordAnd
| TokenKind::WordOr
| TokenKind::WordNot
| TokenKind::WordXor
)
}
#[inline]
pub fn is_low_precedence_word_operator(self) -> bool {
matches!(
self,
TokenKind::WordAnd | TokenKind::WordOr | TokenKind::WordNot | TokenKind::WordXor
)
}
#[inline]
pub fn is_open_delimiter(self) -> bool {
matches!(self, TokenKind::LeftParen | TokenKind::LeftBrace | TokenKind::LeftBracket)
}
#[inline]
pub fn is_close_delimiter(self) -> bool {
matches!(self, TokenKind::RightParen | TokenKind::RightBrace | TokenKind::RightBracket)
}
#[inline]
pub fn matching_delimiter(self) -> Option<Self> {
match self {
TokenKind::LeftParen => Some(TokenKind::RightParen),
TokenKind::RightParen => Some(TokenKind::LeftParen),
TokenKind::LeftBrace => Some(TokenKind::RightBrace),
TokenKind::RightBrace => Some(TokenKind::LeftBrace),
TokenKind::LeftBracket => Some(TokenKind::RightBracket),
TokenKind::RightBracket => Some(TokenKind::LeftBracket),
_ => None,
}
}
#[inline]
pub fn is_quote_like(self) -> bool {
matches!(
self,
TokenKind::Regex
| TokenKind::Substitution
| TokenKind::Transliteration
| TokenKind::QuoteSingle
| TokenKind::QuoteDouble
| TokenKind::QuoteWords
| TokenKind::QuoteCommand
| TokenKind::HeredocStart
)
}
#[inline]
pub fn is_recovery_boundary(self) -> bool {
self == TokenKind::Semicolon || self.is_close_delimiter() || self == TokenKind::Eof
}
pub fn from_keyword(spelling: &str) -> Option<TokenKind> {
match spelling {
"my" => Some(TokenKind::My),
"our" => Some(TokenKind::Our),
"local" => Some(TokenKind::Local),
"state" => Some(TokenKind::State),
"sub" => Some(TokenKind::Sub),
"if" => Some(TokenKind::If),
"elsif" => Some(TokenKind::Elsif),
"else" => Some(TokenKind::Else),
"unless" => Some(TokenKind::Unless),
"while" => Some(TokenKind::While),
"until" => Some(TokenKind::Until),
"for" => Some(TokenKind::For),
"foreach" => Some(TokenKind::Foreach),
"return" => Some(TokenKind::Return),
"package" => Some(TokenKind::Package),
"use" => Some(TokenKind::Use),
"no" => Some(TokenKind::No),
"BEGIN" => Some(TokenKind::Begin),
"END" => Some(TokenKind::End),
"CHECK" => Some(TokenKind::Check),
"INIT" => Some(TokenKind::Init),
"UNITCHECK" => Some(TokenKind::Unitcheck),
"eval" => Some(TokenKind::Eval),
"do" => Some(TokenKind::Do),
"given" => Some(TokenKind::Given),
"when" => Some(TokenKind::When),
"default" => Some(TokenKind::Default),
"try" => Some(TokenKind::Try),
"catch" => Some(TokenKind::Catch),
"finally" => Some(TokenKind::Finally),
"continue" => Some(TokenKind::Continue),
"next" => Some(TokenKind::Next),
"last" => Some(TokenKind::Last),
"redo" => Some(TokenKind::Redo),
"goto" => Some(TokenKind::Goto),
"class" => Some(TokenKind::Class),
"method" => Some(TokenKind::Method),
"field" => Some(TokenKind::Field),
"format" => Some(TokenKind::Format),
"undef" => Some(TokenKind::Undef),
"defer" => Some(TokenKind::Defer),
"and" => Some(TokenKind::WordAnd),
"or" => Some(TokenKind::WordOr),
"not" => Some(TokenKind::WordNot),
"xor" => Some(TokenKind::WordXor),
"cmp" => Some(TokenKind::StringCompare),
_ => None,
}
}
pub fn from_operator(spelling: &str) -> Option<TokenKind> {
match spelling {
"=" => Some(TokenKind::Assign),
"+" => Some(TokenKind::Plus),
"-" => Some(TokenKind::Minus),
"*" => Some(TokenKind::Star),
"/" => Some(TokenKind::Slash),
"%" => Some(TokenKind::Percent),
"**" => Some(TokenKind::Power),
"<<" => Some(TokenKind::LeftShift),
">>" => Some(TokenKind::RightShift),
"&" => Some(TokenKind::BitwiseAnd),
"|" => Some(TokenKind::BitwiseOr),
"^" => Some(TokenKind::BitwiseXor),
"~" => Some(TokenKind::BitwiseNot),
"+=" => Some(TokenKind::PlusAssign),
"-=" => Some(TokenKind::MinusAssign),
"*=" => Some(TokenKind::StarAssign),
"/=" => Some(TokenKind::SlashAssign),
"%=" => Some(TokenKind::PercentAssign),
".=" => Some(TokenKind::DotAssign),
"&=" => Some(TokenKind::AndAssign),
"|=" => Some(TokenKind::OrAssign),
"^=" => Some(TokenKind::XorAssign),
"**=" => Some(TokenKind::PowerAssign),
"<<=" => Some(TokenKind::LeftShiftAssign),
">>=" => Some(TokenKind::RightShiftAssign),
"&&=" => Some(TokenKind::LogicalAndAssign),
"||=" => Some(TokenKind::LogicalOrAssign),
"//=" => Some(TokenKind::DefinedOrAssign),
"==" => Some(TokenKind::Equal),
"!=" => Some(TokenKind::NotEqual),
"=~" => Some(TokenKind::Match),
"!~" => Some(TokenKind::NotMatch),
"~~" => Some(TokenKind::SmartMatch),
"<" => Some(TokenKind::Less),
">" => Some(TokenKind::Greater),
"<=" => Some(TokenKind::LessEqual),
">=" => Some(TokenKind::GreaterEqual),
"<=>" => Some(TokenKind::Spaceship),
"&&" => Some(TokenKind::And),
"||" => Some(TokenKind::Or),
"!" => Some(TokenKind::Not),
"//" => Some(TokenKind::DefinedOr),
"->" => Some(TokenKind::Arrow),
"=>" => Some(TokenKind::FatArrow),
"." => Some(TokenKind::Dot),
".." => Some(TokenKind::Range),
"..." => Some(TokenKind::Ellipsis),
"++" => Some(TokenKind::Increment),
"--" => Some(TokenKind::Decrement),
"::" => Some(TokenKind::DoubleColon),
"?" => Some(TokenKind::Question),
":" => Some(TokenKind::Colon),
"\\" => Some(TokenKind::Backslash),
_ => None,
}
}
pub fn from_delimiter(spelling: &str) -> Option<TokenKind> {
match spelling {
"(" => Some(TokenKind::LeftParen),
")" => Some(TokenKind::RightParen),
"{" => Some(TokenKind::LeftBrace),
"}" => Some(TokenKind::RightBrace),
"[" => Some(TokenKind::LeftBracket),
"]" => Some(TokenKind::RightBracket),
";" => Some(TokenKind::Semicolon),
"," => Some(TokenKind::Comma),
_ => None,
}
}
pub fn from_sigil(spelling: &str) -> Option<TokenKind> {
match spelling {
"$" => Some(TokenKind::ScalarSigil),
"@" => Some(TokenKind::ArraySigil),
"%" => Some(TokenKind::HashSigil),
"&" => Some(TokenKind::SubSigil),
"*" => Some(TokenKind::GlobSigil),
_ => None,
}
}
pub fn canonical_spelling(self) -> Option<&'static str> {
spelling_for_kind(self, KEYWORD_SPELLINGS)
.or_else(|| spelling_for_kind(self, OPERATOR_SPELLINGS))
.or_else(|| spelling_for_kind(self, DELIMITER_SPELLINGS))
.or_else(|| spelling_for_kind(self, SIGIL_SPELLINGS))
}
pub fn display_name(self) -> &'static str {
match self {
TokenKind::My => "'my'",
TokenKind::Our => "'our'",
TokenKind::Local => "'local'",
TokenKind::State => "'state'",
TokenKind::Sub => "'sub'",
TokenKind::If => "'if'",
TokenKind::Elsif => "'elsif'",
TokenKind::Else => "'else'",
TokenKind::Unless => "'unless'",
TokenKind::While => "'while'",
TokenKind::Until => "'until'",
TokenKind::For => "'for'",
TokenKind::Foreach => "'foreach'",
TokenKind::Return => "'return'",
TokenKind::Package => "'package'",
TokenKind::Use => "'use'",
TokenKind::No => "'no'",
TokenKind::Begin => "'BEGIN'",
TokenKind::End => "'END'",
TokenKind::Check => "'CHECK'",
TokenKind::Init => "'INIT'",
TokenKind::Unitcheck => "'UNITCHECK'",
TokenKind::Eval => "'eval'",
TokenKind::Do => "'do'",
TokenKind::Given => "'given'",
TokenKind::When => "'when'",
TokenKind::Default => "'default'",
TokenKind::Try => "'try'",
TokenKind::Catch => "'catch'",
TokenKind::Finally => "'finally'",
TokenKind::Continue => "'continue'",
TokenKind::Next => "'next'",
TokenKind::Last => "'last'",
TokenKind::Redo => "'redo'",
TokenKind::Goto => "'goto'",
TokenKind::Class => "'class'",
TokenKind::Method => "'method'",
TokenKind::Field => "'field'",
TokenKind::Format => "'format'",
TokenKind::Undef => "'undef'",
TokenKind::Defer => "'defer'",
TokenKind::Assign => "'='",
TokenKind::Plus => "'+'",
TokenKind::Minus => "'-'",
TokenKind::Star => "'*'",
TokenKind::Slash => "'/'",
TokenKind::Percent => "'%'",
TokenKind::Power => "'**'",
TokenKind::LeftShift => "'<<'",
TokenKind::RightShift => "'>>'",
TokenKind::BitwiseAnd => "'&'",
TokenKind::BitwiseOr => "'|'",
TokenKind::BitwiseXor => "'^'",
TokenKind::BitwiseNot => "'~'",
TokenKind::PlusAssign => "'+='",
TokenKind::MinusAssign => "'-='",
TokenKind::StarAssign => "'*='",
TokenKind::SlashAssign => "'/='",
TokenKind::PercentAssign => "'%='",
TokenKind::DotAssign => "'.='",
TokenKind::AndAssign => "'&='",
TokenKind::OrAssign => "'|='",
TokenKind::XorAssign => "'^='",
TokenKind::PowerAssign => "'**='",
TokenKind::LeftShiftAssign => "'<<='",
TokenKind::RightShiftAssign => "'>>='",
TokenKind::LogicalAndAssign => "'&&='",
TokenKind::LogicalOrAssign => "'||='",
TokenKind::DefinedOrAssign => "'//='",
TokenKind::Equal => "'=='",
TokenKind::NotEqual => "'!='",
TokenKind::Match => "'=~'",
TokenKind::NotMatch => "'!~'",
TokenKind::SmartMatch => "'~~'",
TokenKind::Less => "'<'",
TokenKind::Greater => "'>'",
TokenKind::LessEqual => "'<='",
TokenKind::GreaterEqual => "'>='",
TokenKind::Spaceship => "'<=>'",
TokenKind::StringCompare => "'cmp'",
TokenKind::And => "'&&'",
TokenKind::Or => "'||'",
TokenKind::Not => "'!'",
TokenKind::DefinedOr => "'//'",
TokenKind::WordAnd => "'and'",
TokenKind::WordOr => "'or'",
TokenKind::WordNot => "'not'",
TokenKind::WordXor => "'xor'",
TokenKind::Arrow => "'->'",
TokenKind::FatArrow => "'=>'",
TokenKind::Dot => "'.'",
TokenKind::Range => "'..'",
TokenKind::Ellipsis => "'...'",
TokenKind::Increment => "'++'",
TokenKind::Decrement => "'--'",
TokenKind::DoubleColon => "'::'",
TokenKind::Question => "'?'",
TokenKind::Colon => "':'",
TokenKind::Backslash => "'\\'",
TokenKind::LeftParen => "'('",
TokenKind::RightParen => "')'",
TokenKind::LeftBrace => "'{'",
TokenKind::RightBrace => "'}'",
TokenKind::LeftBracket => "'['",
TokenKind::RightBracket => "']'",
TokenKind::Semicolon => "';'",
TokenKind::Comma => "','",
TokenKind::Number => "number",
TokenKind::String => "string",
TokenKind::Regex => "regex",
TokenKind::Substitution => "substitution (s///)",
TokenKind::Transliteration => "transliteration (tr///)",
TokenKind::QuoteSingle => "q// string",
TokenKind::QuoteDouble => "qq// string",
TokenKind::QuoteWords => "qw() word list",
TokenKind::QuoteCommand => "qx// command",
TokenKind::HeredocStart => "heredoc (<<)",
TokenKind::HeredocBody => "heredoc body",
TokenKind::FormatBody => "format body",
TokenKind::DataMarker => "data marker (__DATA__ or __END__)",
TokenKind::DataBody => "data section body",
TokenKind::VString => "version string",
TokenKind::UnknownRest => "unparsed remainder",
TokenKind::HeredocDepthLimit => "heredoc depth limit exceeded",
TokenKind::Identifier => "identifier",
TokenKind::ScalarSigil => "'$'",
TokenKind::ArraySigil => "'@'",
TokenKind::HashSigil => "'%'",
TokenKind::SubSigil => "'&'",
TokenKind::GlobSigil => "'*'",
TokenKind::Eof => "end of input",
TokenKind::Unknown => "unknown token",
}
}
}
fn spelling_for_kind(
kind: TokenKind,
spellings: &'static [(&'static str, TokenKind)],
) -> Option<&'static str> {
spellings.iter().find_map(|&(spelling, candidate)| (candidate == kind).then_some(spelling))
}
const TOKEN_KIND_ALL: [TokenKind; 132] = [
TokenKind::My,
TokenKind::Our,
TokenKind::Local,
TokenKind::State,
TokenKind::Sub,
TokenKind::If,
TokenKind::Elsif,
TokenKind::Else,
TokenKind::Unless,
TokenKind::While,
TokenKind::Until,
TokenKind::For,
TokenKind::Foreach,
TokenKind::Return,
TokenKind::Package,
TokenKind::Use,
TokenKind::No,
TokenKind::Begin,
TokenKind::End,
TokenKind::Check,
TokenKind::Init,
TokenKind::Unitcheck,
TokenKind::Eval,
TokenKind::Do,
TokenKind::Given,
TokenKind::When,
TokenKind::Default,
TokenKind::Try,
TokenKind::Catch,
TokenKind::Finally,
TokenKind::Continue,
TokenKind::Next,
TokenKind::Last,
TokenKind::Redo,
TokenKind::Goto,
TokenKind::Class,
TokenKind::Method,
TokenKind::Field,
TokenKind::Format,
TokenKind::Undef,
TokenKind::Defer,
TokenKind::Assign,
TokenKind::Plus,
TokenKind::Minus,
TokenKind::Star,
TokenKind::Slash,
TokenKind::Percent,
TokenKind::Power,
TokenKind::LeftShift,
TokenKind::RightShift,
TokenKind::BitwiseAnd,
TokenKind::BitwiseOr,
TokenKind::BitwiseXor,
TokenKind::BitwiseNot,
TokenKind::PlusAssign,
TokenKind::MinusAssign,
TokenKind::StarAssign,
TokenKind::SlashAssign,
TokenKind::PercentAssign,
TokenKind::DotAssign,
TokenKind::AndAssign,
TokenKind::OrAssign,
TokenKind::XorAssign,
TokenKind::PowerAssign,
TokenKind::LeftShiftAssign,
TokenKind::RightShiftAssign,
TokenKind::LogicalAndAssign,
TokenKind::LogicalOrAssign,
TokenKind::DefinedOrAssign,
TokenKind::Equal,
TokenKind::NotEqual,
TokenKind::Match,
TokenKind::NotMatch,
TokenKind::SmartMatch,
TokenKind::Less,
TokenKind::Greater,
TokenKind::LessEqual,
TokenKind::GreaterEqual,
TokenKind::Spaceship,
TokenKind::StringCompare,
TokenKind::And,
TokenKind::Or,
TokenKind::Not,
TokenKind::DefinedOr,
TokenKind::WordAnd,
TokenKind::WordOr,
TokenKind::WordNot,
TokenKind::WordXor,
TokenKind::Arrow,
TokenKind::FatArrow,
TokenKind::Dot,
TokenKind::Range,
TokenKind::Ellipsis,
TokenKind::Increment,
TokenKind::Decrement,
TokenKind::DoubleColon,
TokenKind::Question,
TokenKind::Colon,
TokenKind::Backslash,
TokenKind::LeftParen,
TokenKind::RightParen,
TokenKind::LeftBrace,
TokenKind::RightBrace,
TokenKind::LeftBracket,
TokenKind::RightBracket,
TokenKind::Semicolon,
TokenKind::Comma,
TokenKind::Number,
TokenKind::String,
TokenKind::Regex,
TokenKind::Substitution,
TokenKind::Transliteration,
TokenKind::QuoteSingle,
TokenKind::QuoteDouble,
TokenKind::QuoteWords,
TokenKind::QuoteCommand,
TokenKind::HeredocStart,
TokenKind::HeredocBody,
TokenKind::FormatBody,
TokenKind::DataMarker,
TokenKind::DataBody,
TokenKind::VString,
TokenKind::UnknownRest,
TokenKind::HeredocDepthLimit,
TokenKind::Identifier,
TokenKind::ScalarSigil,
TokenKind::ArraySigil,
TokenKind::HashSigil,
TokenKind::SubSigil,
TokenKind::GlobSigil,
TokenKind::Eof,
TokenKind::Unknown,
];