use crate::{
equivalence::{Equivalence, EQUIVALENCE_CLASS},
error::Error,
identifier,
number::{parse_exponent, parse_number, parse_number_decimal, parse_number_radix},
state::*,
string,
token::Token,
};
use std::str;
#[derive(Debug)]
struct StateMachine<S: State> {
state: S,
}
impl<S: State> StateMachine<S> {
#[allow(clippy::new_ret_no_self)]
fn new() -> StateMachine<InputElementDiv> {
StateMachine {
state: InputElementDiv,
}
}
fn is_final(&self) -> bool {
self.state.is_final()
}
}
#[derive(Debug)]
enum StateMachineWrapper {
LineTerminator(StateMachine<LineTerminator>),
WhiteSpace(StateMachine<WhiteSpace>),
SingleLineCommentAcc(StateMachine<SingleLineCommentAcc>),
MultiLineCommentAcc(StateMachine<MultiLineCommentAcc>),
DotPart(StateMachine<DotPart>),
Comma(StateMachine<Comma>),
CommaAcc(StateMachine<CommaAcc>),
Semicolon(StateMachine<Semicolon>),
SemicolonAcc(StateMachine<SemicolonAcc>),
LtAcc(StateMachine<LtAcc>),
GtAcc(StateMachine<GtAcc>),
AssignAcc(StateMachine<AssignAcc>),
ExclamationAcc(StateMachine<ExclamationAcc>),
PlusAcc(StateMachine<PlusAcc>),
MinusAcc(StateMachine<MinusAcc>),
MultiAcc(StateMachine<MultiAcc>),
ModAcc(StateMachine<ModAcc>),
AndAcc(StateMachine<AndAcc>),
OrAcc(StateMachine<OrAcc>),
Tilde(StateMachine<Tilde>),
TildeAcc(StateMachine<TildeAcc>),
QuestionMark(StateMachine<QuestionMark>),
QuestionMarkAcc(StateMachine<QuestionMarkAcc>),
ColonAcc(StateMachine<ColonAcc>),
ExclusiveOrAcc(StateMachine<ExclusiveOrAcc>),
String(StateMachine<String>),
Char(StateMachine<Char>),
BinaryAcc(StateMachine<BinaryAcc>),
OctalAcc(StateMachine<OctalAcc>),
HexAcc(StateMachine<HexAcc>),
DecimalAcc(StateMachine<DecimalAcc>),
DecimalDigitsAcc(StateMachine<DecimalDigitsAcc>),
DecimalExponentAcc(StateMachine<DecimalExponentAcc>),
DecimalExponentSignedAcc(StateMachine<DecimalExponentSignedAcc>),
Identifier(StateMachine<Identifier>),
SlashAcc(StateMachine<SlashAcc>),
LBraceAcc(StateMachine<LBraceAcc>),
RBraceAcc(StateMachine<RBraceAcc>),
LParenAcc(StateMachine<LParenAcc>),
RParenAcc(StateMachine<RParenAcc>),
LBracketAcc(StateMachine<LBracketAcc>),
RBracketAcc(StateMachine<RBracketAcc>),
InputElementDiv(StateMachine<InputElementDiv>),
Slash(StateMachine<Slash>),
SingleLineComment(StateMachine<SingleLineComment>),
MultiLineComment(StateMachine<MultiLineComment>),
MultiLineCommentStar(StateMachine<MultiLineCommentStar>),
Lt(StateMachine<Lt>),
Gt(StateMachine<Gt>),
Colon(StateMachine<Colon>),
LBrace(StateMachine<LBrace>),
LParen(StateMachine<LParen>),
RParen(StateMachine<RParen>),
LBracket(StateMachine<LBracket>),
RBracket(StateMachine<RBracket>),
RBrace(StateMachine<RBrace>),
Assign(StateMachine<Assign>),
Exclamation(StateMachine<Exclamation>),
Plus(StateMachine<Plus>),
Minus(StateMachine<Minus>),
Multi(StateMachine<Multi>),
Mod(StateMachine<Mod>),
And(StateMachine<And>),
Or(StateMachine<Or>),
ExclusiveOr(StateMachine<ExclusiveOr>),
SawZero(StateMachine<SawZero>),
Binary(StateMachine<Binary>),
Octal(StateMachine<Octal>),
Hex(StateMachine<Hex>),
Decimal(StateMachine<Decimal>),
DecimalDigits(StateMachine<DecimalDigits>),
DecimalExponent(StateMachine<DecimalExponent>),
DecimalExponentSigned(StateMachine<DecimalExponentSigned>),
}
edge!(InputElementDiv, LineTerminator);
edge!(InputElementDiv, WhiteSpace);
edge!(InputElementDiv, Slash);
edge!(InputElementDiv, DotPart);
edge!(Slash, SlashAcc);
edge!(Slash, SingleLineComment);
edge!(Slash, MultiLineComment);
edge!(SingleLineComment, SingleLineCommentAcc);
edge!(MultiLineComment, MultiLineCommentStar);
edge!(MultiLineCommentStar, MultiLineCommentAcc);
edge!(InputElementDiv, Identifier);
edge!(InputElementDiv, LBrace);
edge!(LBrace, LBraceAcc);
edge!(InputElementDiv, RBrace);
edge!(RBrace, RBraceAcc);
edge!(InputElementDiv, LParen);
edge!(LParen, LParenAcc);
edge!(InputElementDiv, RParen);
edge!(RParen, RParenAcc);
edge!(InputElementDiv, LBracket);
edge!(LBracket, LBracketAcc);
edge!(InputElementDiv, RBracket);
edge!(RBracket, RBracketAcc);
edge!(InputElementDiv, Semicolon);
edge!(Semicolon, SemicolonAcc);
edge!(InputElementDiv, Comma);
edge!(Comma, CommaAcc);
edge!(InputElementDiv, Colon);
edge!(Colon, ColonAcc);
edge!(InputElementDiv, QuestionMark);
edge!(QuestionMark, QuestionMarkAcc);
edge!(InputElementDiv, Tilde);
edge!(Tilde, TildeAcc);
edge!(InputElementDiv, Lt);
edge!(Lt, LtAcc);
edge!(InputElementDiv, Gt);
edge!(Gt, GtAcc);
edge!(InputElementDiv, Assign);
edge!(Assign, AssignAcc);
edge!(InputElementDiv, Exclamation);
edge!(Exclamation, ExclamationAcc);
edge!(InputElementDiv, Plus);
edge!(Plus, PlusAcc);
edge!(InputElementDiv, Multi);
edge!(Multi, MultiAcc);
edge!(InputElementDiv, Mod);
edge!(Mod, ModAcc);
edge!(InputElementDiv, Minus);
edge!(Minus, MinusAcc);
edge!(InputElementDiv, Or);
edge!(Or, OrAcc);
edge!(InputElementDiv, ExclusiveOr);
edge!(ExclusiveOr, ExclusiveOrAcc);
edge!(InputElementDiv, String);
edge!(InputElementDiv, Char);
edge!(And, AndAcc);
edge!(InputElementDiv, And);
edge!(InputElementDiv, SawZero);
edge!(SawZero, Decimal);
edge!(SawZero, DecimalAcc);
edge!(InputElementDiv, Decimal);
edge!(Decimal, DecimalAcc);
edge!(Decimal, DecimalExponent);
edge!(DecimalDigits, DecimalExponent);
edge!(DecimalDigits, DecimalDigitsAcc);
edge!(DecimalExponent, DecimalExponentSigned);
edge!(DecimalExponentSigned, DecimalExponentSignedAcc);
edge!(DecimalExponent, DecimalExponentAcc);
edge!(Decimal, DecimalDigits);
edge!(InputElementDiv, Hex);
edge!(Hex, HexAcc);
edge!(SawZero, Hex);
edge!(InputElementDiv, Binary);
edge!(Binary, BinaryAcc);
edge!(SawZero, Binary);
edge!(InputElementDiv, Octal);
edge!(Octal, OctalAcc);
edge!(SawZero, Octal);
edge!(MultiLineCommentStar, MultiLineComment);
edge!(LineTerminator, HELL);
impl StateMachineWrapper {
#[inline]
fn step(self, e: Equivalence) -> Self {
match (self, e) {
(StateMachineWrapper::InputElementDiv(s), Equivalence::LineTerminator) => {
StateMachineWrapper::LineTerminator(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::White) => {
StateMachineWrapper::WhiteSpace(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::Slash) => {
StateMachineWrapper::Slash(s.into())
} (StateMachineWrapper::InputElementDiv(s), Equivalence::Dot) => {
StateMachineWrapper::DotPart(s.into())
}
(StateMachineWrapper::Slash(s), Equivalence::Assign) => {
StateMachineWrapper::SlashAcc(s.into())
} (StateMachineWrapper::Slash(s), Equivalence::Slash) => {
StateMachineWrapper::SingleLineComment(s.into())
} (StateMachineWrapper::Slash(s), Equivalence::Multi) => {
StateMachineWrapper::MultiLineComment(s.into())
}
(StateMachineWrapper::Slash(s), _) => StateMachineWrapper::SlashAcc(s.into()),
(StateMachineWrapper::SingleLineComment(s), Equivalence::LineTerminator) => {
StateMachineWrapper::SingleLineCommentAcc(s.into())
}
(StateMachineWrapper::SingleLineComment(s), _) => {
StateMachineWrapper::SingleLineComment(s)
}
(StateMachineWrapper::MultiLineComment(s), Equivalence::Multi) => {
StateMachineWrapper::MultiLineCommentStar(s.into())
}
(StateMachineWrapper::MultiLineCommentStar(s), Equivalence::Multi) => {
StateMachineWrapper::MultiLineCommentStar(s)
}
(StateMachineWrapper::MultiLineCommentStar(s), Equivalence::Slash) => {
StateMachineWrapper::MultiLineCommentAcc(s.into())
}
(StateMachineWrapper::MultiLineComment(s), _) => {
StateMachineWrapper::MultiLineComment(s)
}
(StateMachineWrapper::MultiLineCommentStar(s), _) => {
StateMachineWrapper::MultiLineComment(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::Letter) => {
StateMachineWrapper::Identifier(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::A) => {
StateMachineWrapper::Identifier(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::B) => {
StateMachineWrapper::Identifier(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::C) => {
StateMachineWrapper::Identifier(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::D) => {
StateMachineWrapper::Identifier(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::E) => {
StateMachineWrapper::Identifier(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::F) => {
StateMachineWrapper::Identifier(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::O) => {
StateMachineWrapper::Identifier(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::X) => {
StateMachineWrapper::Identifier(s.into())
}
(StateMachineWrapper::LBrace(s), _) => StateMachineWrapper::LBraceAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::LBrace) => {
StateMachineWrapper::LBrace(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::RBrace) => {
StateMachineWrapper::RBrace(s.into())
}
(StateMachineWrapper::RBrace(s), _) => StateMachineWrapper::RBraceAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::LParen) => {
StateMachineWrapper::LParen(s.into())
}
(StateMachineWrapper::LParen(s), _) => StateMachineWrapper::LParenAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::RParen) => {
StateMachineWrapper::RParen(s.into())
}
(StateMachineWrapper::RParen(s), _) => StateMachineWrapper::RParenAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::LBracket) => {
StateMachineWrapper::LBracket(s.into())
}
(StateMachineWrapper::LBracket(s), _) => StateMachineWrapper::LBracketAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::RBracket) => {
StateMachineWrapper::RBracket(s.into())
}
(StateMachineWrapper::RBracket(s), _) => StateMachineWrapper::RBracketAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::Semicolon) => {
StateMachineWrapper::Semicolon(s.into())
}
(StateMachineWrapper::Semicolon(s), _) => StateMachineWrapper::SemicolonAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::Comma) => {
StateMachineWrapper::Comma(s.into())
}
(StateMachineWrapper::Comma(s), _) => StateMachineWrapper::CommaAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::Colon) => {
StateMachineWrapper::Colon(s.into())
}
(StateMachineWrapper::Colon(s), _) => StateMachineWrapper::ColonAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::QuestionMark) => {
StateMachineWrapper::QuestionMark(s.into())
}
(StateMachineWrapper::QuestionMark(s), _) => {
StateMachineWrapper::QuestionMarkAcc(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::Tilde) => {
StateMachineWrapper::Tilde(s.into())
}
(StateMachineWrapper::Tilde(s), _) => StateMachineWrapper::TildeAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::Lt) => {
StateMachineWrapper::Lt(s.into())
}
(StateMachineWrapper::Lt(s), Equivalence::Assign) => StateMachineWrapper::Lt(s),
(StateMachineWrapper::Lt(s), Equivalence::Lt) => StateMachineWrapper::Lt(s),
(StateMachineWrapper::Lt(s), _) => StateMachineWrapper::LtAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::Gt) => {
StateMachineWrapper::Gt(s.into())
}
(StateMachineWrapper::Gt(s), Equivalence::Assign) => StateMachineWrapper::Gt(s),
(StateMachineWrapper::Gt(s), Equivalence::Gt) => StateMachineWrapper::Gt(s),
(StateMachineWrapper::Gt(s), _) => StateMachineWrapper::GtAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::Assign) => {
StateMachineWrapper::Assign(s.into())
}
(StateMachineWrapper::Assign(s), Equivalence::Assign) => StateMachineWrapper::Assign(s),
(StateMachineWrapper::Assign(s), _) => StateMachineWrapper::AssignAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::Exclamation) => {
StateMachineWrapper::Exclamation(s.into())
}
(StateMachineWrapper::Exclamation(s), Equivalence::Assign) => {
StateMachineWrapper::Exclamation(s)
}
(StateMachineWrapper::Exclamation(s), _) => {
StateMachineWrapper::ExclamationAcc(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::Plus) => {
StateMachineWrapper::Plus(s.into())
}
(StateMachineWrapper::Plus(s), Equivalence::Plus) => StateMachineWrapper::Plus(s),
(StateMachineWrapper::Plus(s), Equivalence::Assign) => StateMachineWrapper::Plus(s),
(StateMachineWrapper::Plus(s), _) => StateMachineWrapper::PlusAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::Minus) => {
StateMachineWrapper::Minus(s.into())
}
(StateMachineWrapper::Minus(s), Equivalence::Minus) => StateMachineWrapper::Minus(s),
(StateMachineWrapper::Minus(s), Equivalence::Gt) => StateMachineWrapper::Minus(s),
(StateMachineWrapper::Minus(s), Equivalence::Assign) => StateMachineWrapper::Minus(s),
(StateMachineWrapper::Minus(s), _) => StateMachineWrapper::MinusAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::Multi) => {
StateMachineWrapper::Multi(s.into())
}
(StateMachineWrapper::Multi(s), Equivalence::Multi) => StateMachineWrapper::Multi(s),
(StateMachineWrapper::Multi(s), Equivalence::Assign) => StateMachineWrapper::Multi(s),
(StateMachineWrapper::Multi(s), _) => StateMachineWrapper::MultiAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::Mod) => {
StateMachineWrapper::Mod(s.into())
}
(StateMachineWrapper::Mod(s), Equivalence::Mod) => StateMachineWrapper::Mod(s),
(StateMachineWrapper::Mod(s), Equivalence::Assign) => StateMachineWrapper::Mod(s),
(StateMachineWrapper::Mod(s), _) => StateMachineWrapper::ModAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::SingleAnd) => {
StateMachineWrapper::And(s.into())
}
(StateMachineWrapper::And(s), Equivalence::SingleAnd) => StateMachineWrapper::And(s),
(StateMachineWrapper::And(s), Equivalence::Assign) => StateMachineWrapper::And(s),
(StateMachineWrapper::And(s), _) => StateMachineWrapper::AndAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::InclusiveOr) => {
StateMachineWrapper::Or(s.into())
}
(StateMachineWrapper::Or(s), Equivalence::InclusiveOr) => StateMachineWrapper::Or(s),
(StateMachineWrapper::Or(s), Equivalence::Assign) => StateMachineWrapper::Or(s),
(StateMachineWrapper::Or(s), _) => StateMachineWrapper::OrAcc(s.into()),
(StateMachineWrapper::InputElementDiv(s), Equivalence::ExclusiveOr) => {
StateMachineWrapper::ExclusiveOr(s.into())
}
(StateMachineWrapper::ExclusiveOr(s), Equivalence::ExclusiveOr) => {
StateMachineWrapper::ExclusiveOr(s)
}
(StateMachineWrapper::ExclusiveOr(s), Equivalence::Assign) => {
StateMachineWrapper::ExclusiveOr(s)
}
(StateMachineWrapper::ExclusiveOr(s), _) => {
StateMachineWrapper::ExclusiveOrAcc(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::String) => {
StateMachineWrapper::String(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::Char) => {
StateMachineWrapper::Char(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::Zero) => {
StateMachineWrapper::SawZero(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::One) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::Two) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::Three) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::Four) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::Five) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::Six) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::Seven) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::InputElementDiv(s), Equivalence::EightNine) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::SawZero(s), Equivalence::B) => {
StateMachineWrapper::Binary(s.into())
}
(StateMachineWrapper::SawZero(s), Equivalence::O) => {
StateMachineWrapper::Octal(s.into())
}
(StateMachineWrapper::SawZero(s), Equivalence::X) => StateMachineWrapper::Hex(s.into()),
(StateMachineWrapper::SawZero(s), Equivalence::One) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::SawZero(s), Equivalence::Two) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::SawZero(s), Equivalence::Three) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::SawZero(s), Equivalence::Four) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::SawZero(s), Equivalence::Five) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::SawZero(s), Equivalence::Six) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::SawZero(s), Equivalence::Seven) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::SawZero(s), Equivalence::EightNine) => {
StateMachineWrapper::Decimal(s.into())
}
(StateMachineWrapper::SawZero(s), _) => StateMachineWrapper::DecimalAcc(s.into()),
(StateMachineWrapper::Decimal(s), Equivalence::Zero) => StateMachineWrapper::Decimal(s),
(StateMachineWrapper::Decimal(s), Equivalence::One) => StateMachineWrapper::Decimal(s),
(StateMachineWrapper::Decimal(s), Equivalence::Two) => StateMachineWrapper::Decimal(s),
(StateMachineWrapper::Decimal(s), Equivalence::Three) => {
StateMachineWrapper::Decimal(s)
}
(StateMachineWrapper::Decimal(s), Equivalence::Four) => StateMachineWrapper::Decimal(s),
(StateMachineWrapper::Decimal(s), Equivalence::Five) => StateMachineWrapper::Decimal(s),
(StateMachineWrapper::Decimal(s), Equivalence::Six) => StateMachineWrapper::Decimal(s),
(StateMachineWrapper::Decimal(s), Equivalence::Seven) => {
StateMachineWrapper::Decimal(s)
}
(StateMachineWrapper::Decimal(s), Equivalence::EightNine) => {
StateMachineWrapper::Decimal(s)
}
(StateMachineWrapper::Decimal(s), Equivalence::Dot) => {
StateMachineWrapper::DecimalDigits(s.into())
}
(StateMachineWrapper::Decimal(s), Equivalence::E) => {
StateMachineWrapper::DecimalExponent(s.into())
}
(StateMachineWrapper::Decimal(s), _) => StateMachineWrapper::DecimalAcc(s.into()),
(StateMachineWrapper::DecimalDigits(s), Equivalence::Zero) => {
StateMachineWrapper::DecimalDigits(s)
}
(StateMachineWrapper::DecimalDigits(s), Equivalence::One) => {
StateMachineWrapper::DecimalDigits(s)
}
(StateMachineWrapper::DecimalDigits(s), Equivalence::Two) => {
StateMachineWrapper::DecimalDigits(s)
}
(StateMachineWrapper::DecimalDigits(s), Equivalence::Three) => {
StateMachineWrapper::DecimalDigits(s)
}
(StateMachineWrapper::DecimalDigits(s), Equivalence::Four) => {
StateMachineWrapper::DecimalDigits(s)
}
(StateMachineWrapper::DecimalDigits(s), Equivalence::Five) => {
StateMachineWrapper::DecimalDigits(s)
}
(StateMachineWrapper::DecimalDigits(s), Equivalence::Six) => {
StateMachineWrapper::DecimalDigits(s)
}
(StateMachineWrapper::DecimalDigits(s), Equivalence::Seven) => {
StateMachineWrapper::DecimalDigits(s)
}
(StateMachineWrapper::DecimalDigits(s), Equivalence::EightNine) => {
StateMachineWrapper::DecimalDigits(s)
}
(StateMachineWrapper::DecimalDigits(s), Equivalence::E) => {
StateMachineWrapper::DecimalExponent(s.into())
}
(StateMachineWrapper::DecimalDigits(s), _) => {
StateMachineWrapper::DecimalDigitsAcc(s.into())
}
(StateMachineWrapper::DecimalExponent(s), Equivalence::Zero) => {
StateMachineWrapper::DecimalExponent(s)
}
(StateMachineWrapper::DecimalExponent(s), Equivalence::One) => {
StateMachineWrapper::DecimalExponent(s)
}
(StateMachineWrapper::DecimalExponent(s), Equivalence::Two) => {
StateMachineWrapper::DecimalExponent(s)
}
(StateMachineWrapper::DecimalExponent(s), Equivalence::Three) => {
StateMachineWrapper::DecimalExponent(s)
}
(StateMachineWrapper::DecimalExponent(s), Equivalence::Four) => {
StateMachineWrapper::DecimalExponent(s)
}
(StateMachineWrapper::DecimalExponent(s), Equivalence::Five) => {
StateMachineWrapper::DecimalExponent(s)
}
(StateMachineWrapper::DecimalExponent(s), Equivalence::Six) => {
StateMachineWrapper::DecimalExponent(s)
}
(StateMachineWrapper::DecimalExponent(s), Equivalence::Seven) => {
StateMachineWrapper::DecimalExponent(s)
}
(StateMachineWrapper::DecimalExponent(s), Equivalence::EightNine) => {
StateMachineWrapper::DecimalExponent(s)
}
(StateMachineWrapper::DecimalExponent(s), Equivalence::Minus) => {
StateMachineWrapper::DecimalExponentSigned(s.into())
}
(StateMachineWrapper::DecimalExponent(s), Equivalence::Plus) => {
StateMachineWrapper::DecimalExponentSigned(s.into())
}
(StateMachineWrapper::DecimalExponent(s), _) => {
StateMachineWrapper::DecimalExponentAcc(s.into())
}
(StateMachineWrapper::DecimalExponentSigned(s), Equivalence::Zero) => {
StateMachineWrapper::DecimalExponentSigned(s)
}
(StateMachineWrapper::DecimalExponentSigned(s), Equivalence::One) => {
StateMachineWrapper::DecimalExponentSigned(s)
}
(StateMachineWrapper::DecimalExponentSigned(s), Equivalence::Two) => {
StateMachineWrapper::DecimalExponentSigned(s)
}
(StateMachineWrapper::DecimalExponentSigned(s), Equivalence::Three) => {
StateMachineWrapper::DecimalExponentSigned(s)
}
(StateMachineWrapper::DecimalExponentSigned(s), Equivalence::Four) => {
StateMachineWrapper::DecimalExponentSigned(s)
}
(StateMachineWrapper::DecimalExponentSigned(s), Equivalence::Five) => {
StateMachineWrapper::DecimalExponentSigned(s)
}
(StateMachineWrapper::DecimalExponentSigned(s), Equivalence::Six) => {
StateMachineWrapper::DecimalExponentSigned(s)
}
(StateMachineWrapper::DecimalExponentSigned(s), Equivalence::Seven) => {
StateMachineWrapper::DecimalExponentSigned(s)
}
(StateMachineWrapper::DecimalExponentSigned(s), Equivalence::EightNine) => {
StateMachineWrapper::DecimalExponentSigned(s)
}
(StateMachineWrapper::DecimalExponentSigned(s), _) => {
StateMachineWrapper::DecimalExponentSignedAcc(s.into())
}
(StateMachineWrapper::Octal(s), Equivalence::Zero) => StateMachineWrapper::Octal(s),
(StateMachineWrapper::Octal(s), Equivalence::One) => StateMachineWrapper::Octal(s),
(StateMachineWrapper::Octal(s), Equivalence::Two) => StateMachineWrapper::Octal(s),
(StateMachineWrapper::Octal(s), Equivalence::Three) => StateMachineWrapper::Octal(s),
(StateMachineWrapper::Octal(s), Equivalence::Four) => StateMachineWrapper::Octal(s),
(StateMachineWrapper::Octal(s), Equivalence::Five) => StateMachineWrapper::Octal(s),
(StateMachineWrapper::Octal(s), Equivalence::Six) => StateMachineWrapper::Octal(s),
(StateMachineWrapper::Octal(s), Equivalence::Seven) => StateMachineWrapper::Octal(s),
(StateMachineWrapper::Octal(s), _) => StateMachineWrapper::OctalAcc(s.into()),
(StateMachineWrapper::Hex(s), Equivalence::Zero) => StateMachineWrapper::Hex(s),
(StateMachineWrapper::Hex(s), Equivalence::One) => StateMachineWrapper::Hex(s),
(StateMachineWrapper::Hex(s), Equivalence::Two) => StateMachineWrapper::Hex(s),
(StateMachineWrapper::Hex(s), Equivalence::Three) => StateMachineWrapper::Hex(s),
(StateMachineWrapper::Hex(s), Equivalence::Four) => StateMachineWrapper::Hex(s),
(StateMachineWrapper::Hex(s), Equivalence::Five) => StateMachineWrapper::Hex(s),
(StateMachineWrapper::Hex(s), Equivalence::Six) => StateMachineWrapper::Hex(s),
(StateMachineWrapper::Hex(s), Equivalence::Seven) => StateMachineWrapper::Hex(s),
(StateMachineWrapper::Hex(s), Equivalence::EightNine) => StateMachineWrapper::Hex(s),
(StateMachineWrapper::Hex(s), Equivalence::A) => StateMachineWrapper::Hex(s),
(StateMachineWrapper::Hex(s), Equivalence::B) => StateMachineWrapper::Hex(s),
(StateMachineWrapper::Hex(s), Equivalence::C) => StateMachineWrapper::Hex(s),
(StateMachineWrapper::Hex(s), Equivalence::D) => StateMachineWrapper::Hex(s),
(StateMachineWrapper::Hex(s), Equivalence::E) => StateMachineWrapper::Hex(s),
(StateMachineWrapper::Hex(s), Equivalence::F) => StateMachineWrapper::Hex(s),
(StateMachineWrapper::Hex(s), _) => StateMachineWrapper::HexAcc(s.into()),
(StateMachineWrapper::Binary(s), Equivalence::One) => StateMachineWrapper::Binary(s),
(StateMachineWrapper::Binary(s), Equivalence::Zero) => StateMachineWrapper::Binary(s),
(StateMachineWrapper::Binary(s), _) => StateMachineWrapper::BinaryAcc(s.into()),
(_, Equivalence::HELL) => {
StateMachineWrapper::InputElementDiv(StateMachine::<InputElementDiv>::new())
}
a => unreachable!("Invalid state: {:?} ", a),
}
}
#[inline]
fn is_final(&self) -> bool {
match self {
StateMachineWrapper::LineTerminator(n) => n.is_final(),
StateMachineWrapper::WhiteSpace(n) => n.is_final(),
StateMachineWrapper::SingleLineCommentAcc(n) => n.is_final(),
StateMachineWrapper::MultiLineCommentAcc(n) => n.is_final(),
StateMachineWrapper::LBrace(n) => n.is_final(),
StateMachineWrapper::LBraceAcc(n) => n.is_final(),
StateMachineWrapper::LParen(n) => n.is_final(),
StateMachineWrapper::RParen(n) => n.is_final(),
StateMachineWrapper::LBracket(n) => n.is_final(),
StateMachineWrapper::RBracket(n) => n.is_final(),
StateMachineWrapper::LParenAcc(n) => n.is_final(),
StateMachineWrapper::RParenAcc(n) => n.is_final(),
StateMachineWrapper::LBracketAcc(n) => n.is_final(),
StateMachineWrapper::RBracketAcc(n) => n.is_final(),
StateMachineWrapper::DotPart(n) => n.is_final(),
StateMachineWrapper::Comma(n) => n.is_final(),
StateMachineWrapper::CommaAcc(n) => n.is_final(),
StateMachineWrapper::Semicolon(n) => n.is_final(),
StateMachineWrapper::SemicolonAcc(n) => n.is_final(),
StateMachineWrapper::LtAcc(n) => n.is_final(),
StateMachineWrapper::GtAcc(n) => n.is_final(),
StateMachineWrapper::AssignAcc(n) => n.is_final(),
StateMachineWrapper::ExclamationAcc(n) => n.is_final(),
StateMachineWrapper::PlusAcc(n) => n.is_final(),
StateMachineWrapper::MinusAcc(n) => n.is_final(),
StateMachineWrapper::MultiAcc(n) => n.is_final(),
StateMachineWrapper::ModAcc(n) => n.is_final(),
StateMachineWrapper::AndAcc(n) => n.is_final(),
StateMachineWrapper::OrAcc(n) => n.is_final(),
StateMachineWrapper::Tilde(n) => n.is_final(),
StateMachineWrapper::TildeAcc(n) => n.is_final(),
StateMachineWrapper::QuestionMark(n) => n.is_final(),
StateMachineWrapper::QuestionMarkAcc(n) => n.is_final(),
StateMachineWrapper::ColonAcc(n) => n.is_final(),
StateMachineWrapper::ExclusiveOrAcc(n) => n.is_final(),
StateMachineWrapper::String(n) => n.is_final(),
StateMachineWrapper::Char(n) => n.is_final(),
StateMachineWrapper::BinaryAcc(n) => n.is_final(),
StateMachineWrapper::OctalAcc(n) => n.is_final(),
StateMachineWrapper::HexAcc(n) => n.is_final(),
StateMachineWrapper::DecimalAcc(n) => n.is_final(),
StateMachineWrapper::DecimalDigitsAcc(n) => n.is_final(),
StateMachineWrapper::DecimalExponentAcc(n) => n.is_final(),
StateMachineWrapper::DecimalExponentSignedAcc(n) => n.is_final(),
StateMachineWrapper::Identifier(n) => n.is_final(),
StateMachineWrapper::SlashAcc(n) => n.is_final(),
StateMachineWrapper::RBrace(n) => n.is_final(),
StateMachineWrapper::RBraceAcc(n) => n.is_final(),
StateMachineWrapper::InputElementDiv(n) => n.is_final(),
StateMachineWrapper::Slash(n) => n.is_final(),
StateMachineWrapper::SingleLineComment(n) => n.is_final(),
StateMachineWrapper::MultiLineComment(n) => n.is_final(),
StateMachineWrapper::Colon(n) => n.is_final(),
StateMachineWrapper::MultiLineCommentStar(n) => n.is_final(),
StateMachineWrapper::Lt(n) => n.is_final(),
StateMachineWrapper::Gt(n) => n.is_final(),
StateMachineWrapper::Assign(n) => n.is_final(),
StateMachineWrapper::Exclamation(n) => n.is_final(),
StateMachineWrapper::Plus(n) => n.is_final(),
StateMachineWrapper::Minus(n) => n.is_final(),
StateMachineWrapper::Multi(n) => n.is_final(),
StateMachineWrapper::Mod(n) => n.is_final(),
StateMachineWrapper::And(n) => n.is_final(),
StateMachineWrapper::Or(n) => n.is_final(),
StateMachineWrapper::ExclusiveOr(n) => n.is_final(),
StateMachineWrapper::SawZero(n) => n.is_final(),
StateMachineWrapper::Binary(n) => n.is_final(),
StateMachineWrapper::Octal(n) => n.is_final(),
StateMachineWrapper::Hex(n) => n.is_final(),
StateMachineWrapper::Decimal(n) => n.is_final(),
StateMachineWrapper::DecimalDigits(n) => n.is_final(),
StateMachineWrapper::DecimalExponent(n) => n.is_final(),
StateMachineWrapper::DecimalExponentSigned(n) => n.is_final(),
}
}
}
#[inline]
pub fn parse(input: &str) -> Result<Vec<Token>, Error> {
let mut st = StateMachineWrapper::InputElementDiv(StateMachine::<InputElementDiv>::new());
let input = input.as_bytes();
let input_len = input.len();
let mut tokens = Vec::with_capacity(input.len());
let mut c_src: usize = 0;
let mut token_len: u64 = 0;
while c_src < input_len {
while !st.is_final() {
let ch = unsafe { *input.get_unchecked(c_src) };
st = st.step(EQUIVALENCE_CLASS[ch as usize]);
c_src += 1;
token_len += 1;
}
if c_src >= input_len {
break;
}
let token = &input[c_src - token_len as usize..c_src - 1];
let token = unsafe { str::from_utf8_unchecked(token) };
let token = super::token::TOKENS
.get(token)
.cloned()
.or_else(|| state_match(st, input, &mut c_src, token_len).unwrap());
c_src -= 1;
if let Some(tok) = token {
tokens.push(tok);
}
st = StateMachineWrapper::InputElementDiv(StateMachine::<InputElementDiv>::new());
token_len = 0;
}
Ok(tokens)
}
#[inline]
fn state_match(
st: StateMachineWrapper,
input: &[u8],
c_src: &mut usize,
token_len: u64,
) -> Result<Option<Token>, Error> {
let res = match st {
StateMachineWrapper::LineTerminator(_) => Some(Token::LineTerminator),
StateMachineWrapper::SingleLineCommentAcc(_) => Some(Token::LineTerminator),
StateMachineWrapper::MultiLineCommentAcc(_) => None,
StateMachineWrapper::SlashAcc(_) => {
if input[*c_src - token_len as usize + 1] == b'=' {
Some(Token::DivAssign)
} else {
Some(Token::Slash)
}
}
StateMachineWrapper::String(_) => Some(string::parse_string(input, c_src)),
StateMachineWrapper::Char(_) => Some(string::parse_char(input, c_src)),
StateMachineWrapper::BinaryAcc(_) => Some(parse_number_radix(input, c_src, token_len, 2)?),
StateMachineWrapper::OctalAcc(_) => Some(parse_number_radix(input, c_src, token_len, 8)?),
StateMachineWrapper::HexAcc(_) => Some(parse_number_radix(input, c_src, token_len, 16)?),
StateMachineWrapper::DecimalAcc(_) => Some(parse_number(input, c_src, token_len)?),
StateMachineWrapper::DotPart(_) => Some(parse_dot(input, c_src)),
StateMachineWrapper::DecimalDigitsAcc(_) => {
Some(parse_number_decimal(input, c_src, token_len)?)
}
StateMachineWrapper::DecimalExponentSignedAcc(_) => {
Some(parse_exponent(input, c_src, token_len)?)
}
StateMachineWrapper::DecimalExponentAcc(_) => {
Some(parse_exponent(input, c_src, token_len)?)
}
StateMachineWrapper::Identifier(_) => Some(identifier::parse_identifier(input, c_src)),
_ => None,
};
*c_src += 1;
Ok(res)
}
#[inline]
fn parse_dot(input: &[u8], c_src: &mut usize) -> Token {
let rest_len = input.len() - *c_src;
if rest_len >= 2 && input[*c_src] == b'.' && input[*c_src + 1] == b'.' {
*c_src += 2;
return Token::ELLIPSIS;
}
Token::Dot
}
#[cfg(test)]
mod tests {
use super::super::*;
should!(
lineterminator_all,
"\u{000A}\u{000D}",
vec![Token::LineTerminator, Token::LineTerminator, Token::EOF]
);
should!(
single_comment,
"// rest // of comment \n",
vec![Token::LineTerminator, Token::EOF]
);
should!(multi_comment, "/** rest // of comment */", vec![Token::EOF]);
should!(
multi_comment_with_newline,
"/** rest // \n of comment */",
vec![Token::EOF]
);
should!(left_curly, "{", vec![Token::LBrace, Token::EOF]);
should!(right_curly, "}", vec![Token::RBrace, Token::EOF]);
should!(left_round, "(", vec![Token::LParen, Token::EOF]);
should!(right_round, ")", vec![Token::RParen, Token::EOF]);
should!(left_square, "[", vec![Token::LBracket, Token::EOF]);
should!(right_square, "]", vec![Token::RBracket, Token::EOF]);
should!(dot, ".", vec![Token::Dot, Token::EOF]);
should!(twodot, "..", vec![Token::Dot, Token::Dot, Token::EOF]);
should!(tripledot, "...", vec![Token::ELLIPSIS, Token::EOF]);
should!(
fourdot,
"....",
vec![Token::ELLIPSIS, Token::Dot, Token::EOF]
);
should!(lesser, "< ", vec![Token::Lt, Token::EOF]);
should!(lesser_double, "<< ", vec![Token::LeftOp, Token::EOF]);
should!(lesser_equal, "<= ", vec![Token::LeOp, Token::EOF]);
should!(
lesser_equal_double,
"<<= ",
vec![Token::LeftAssign, Token::EOF]
);
should!(bigger, "> ", vec![Token::Gt, Token::EOF]);
should!(bigger_equal, ">= ", vec![Token::GeOp, Token::EOF]);
should!(bigger_double, ">> ", vec![Token::RightOp, Token::EOF]);
should!(
bigger_double_equal,
">>= ",
vec![Token::RightAssign, Token::EOF]
);
should!(assign, "= ", vec![Token::Assign, Token::EOF]);
should!(ptr_op, "-> ", vec![Token::PtrOp, Token::EOF]);
should!(assign_double, "== ", vec![Token::EqOp, Token::EOF]);
should!(exclamation, "! ", vec![Token::Exclamation, Token::EOF]);
should!(exclamation_assign, "!= ", vec![Token::NeOp, Token::EOF]);
should!(plus, "+ ", vec![Token::Plus, Token::EOF]);
should!(plus_dobule, "++ ", vec![Token::IncOp, Token::EOF]);
should!(plus_assign, "+= ", vec![Token::AddAssign, Token::EOF]);
should!(minus, "- ", vec![Token::Minus, Token::EOF]);
should!(minus_double, "-- ", vec![Token::DecOp, Token::EOF]);
should!(minus_assign, "-= ", vec![Token::SubAssign, Token::EOF]);
should!(star, "* ", vec![Token::Multi, Token::EOF]);
should!(star_assign, "*= ", vec![Token::MulAssign, Token::EOF]);
should!(percent, "% ", vec![Token::Mod, Token::EOF]);
should!(percent_assign, "%= ", vec![Token::ModAssign, Token::EOF]);
should!(and, "& ", vec![Token::SingleAnd, Token::EOF]);
should!(and_double, "&& ", vec![Token::AndOp, Token::EOF]);
should!(and_assign, "&= ", vec![Token::AndAssign, Token::EOF]);
should!(or, "| ", vec![Token::InclusiveOr, Token::EOF]);
should!(or_double, "|| ", vec![Token::OrOp, Token::EOF]);
should!(or_assign, "|= ", vec![Token::OrAssign, Token::EOF]);
should!(tilde, "~ ", vec![Token::Tilde, Token::EOF]);
should!(colon, ": ", vec![Token::Colon, Token::EOF]);
should!(questionmark, "?", vec![Token::QuestionMark, Token::EOF]);
should!(caret, "^ ", vec![Token::ExclusiveOr, Token::EOF]);
should!(caret_assign, "^= ", vec![Token::XorAssign, Token::EOF]);
should!(slash_assign, "/= ", vec![Token::DivAssign, Token::EOF]);
should!(slash, "/ ", vec![Token::Slash, Token::EOF]);
should!(keyowrd, "auto ", vec![Token::AUTO, Token::EOF]);
should!(comma, ", ", vec![Token::Comma, Token::EOF]);
}