構文

Veryl のパーサはパーサジェネレータ parolを使っています。以下の parol の構文定義が正式な構文です。


%start Veryl
%title "Veryl grammar"
%comment "Empty grammar generated by `parol`"
%user_type VerylToken = crate::veryl_token::VerylToken
%user_type Token = crate::veryl_token::Token

%scanner Embed {
    %auto_newline_off
    %auto_ws_off
}

%scanner Generic {
}

%%

// ----------------------------------------------------------------------------
// Terminal
// ----------------------------------------------------------------------------

// Longest match should be first

CommentsTerm          : <INITIAL, Generic       >"(?:(?:(?://.*(?:\r\n|\r|\n|$))|(?:(?ms)/\u{2a}.*?\u{2a}/))\s*)+"                     : Token;
StringLiteralTerm     : <INITIAL, Generic       >"\u{0022}(?:\\[\u{0022}\\/bfnrt]|u[0-9a-fA-F]{4}|[^\u{0022}\\\u0000-\u001F])*\u{0022}": Token;
ExponentTerm          : <INITIAL, Generic       >/[0-9]+(?:_[0-9]+)*\.[0-9]+(?:_[0-9]+)*[eE][+-]?[0-9]+(?:_[0-9]+)*/                   : Token;
FixedPointTerm        : <INITIAL, Generic       >/[0-9]+(?:_[0-9]+)*\.[0-9]+(?:_[0-9]+)*/                                              : Token;
BasedTerm             : <INITIAL, Generic       >/(?:[0-9]+(?:_[0-9]+)*)?'s?[bodh][0-9a-fA-FxzXZ]+(?:_[0-9a-fA-FxzXZ]+)*/              : Token;
AllBitTerm            : <INITIAL, Generic       >/(?:[0-9]+(?:_[0-9]+)*)?'[01xzXZ]/                                                    : Token;
BaseLessTerm          : <INITIAL, Generic       >/[0-9]+(?:_[0-9]+)*/                                                                  : Token;
MinusColonTerm        : <INITIAL                >'-:'                                                                                  : Token;
MinusGTTerm           : <INITIAL                >'->'                                                                                  : Token;
PlusColonTerm         : <INITIAL                >'+:'                                                                                  : Token;
AssignmentOperatorTerm: <INITIAL                >"\+=|-=|\*=|/=|%=|&=|\|=|\^=|<<=|>>=|<<<=|>>>="                                       : Token;
Operator11Term        : <INITIAL                >"\*\*"                                                                                : Token;
Operator10Term        : <INITIAL                >"/|%"                                                                                 : Token;
Operator09Term        : <INITIAL                >"\+|-"                                                                                : Token;
Operator08Term        : <INITIAL                >"<<<|>>>|<<|>>"                                                                       : Token;
Operator07Term        : <INITIAL                >"<=|>=|<:|>:"                                                                         : Token;
Operator06Term        : <INITIAL                >"===|==\?|!==|!=\?|==|!="                                                             : Token;
Operator02Term        : <INITIAL                >"&&"                                                                                  : Token;
Operator01Term        : <INITIAL                >"\|\|"                                                                                : Token;
Operator05Term        : <INITIAL                >"&"                                                                                   : Token;
Operator04Term        : <INITIAL                >"\^~|\^|~\^"                                                                          : Token;
Operator03Term        : <INITIAL                >"\|"                                                                                  : Token;
UnaryOperatorTerm     : <INITIAL                >"~&|~\||!|~"                                                                          : Token;
BackQuoteTerm         : <INITIAL, Generic       >"`"                                                                                   : Token;
ColonColonLAngleTerm  : <INITIAL, Generic       >'::<'                                                                                 : Token;
ColonColonTerm        : <INITIAL, Generic       >'::'                                                                                  : Token;
ColonTerm             : <INITIAL, Generic       >':'                                                                                   : Token;
CommaTerm             : <INITIAL, Generic       >','                                                                                   : Token;
DotDotEquTerm         : <INITIAL, Generic       >'..='                                                                                 : Token;
DotDotTerm            : <INITIAL, Generic       >'..'                                                                                  : Token;
DotTerm               : <INITIAL, Generic       >'.'                                                                                   : Token;
EquTerm               : <INITIAL, Generic       >'='                                                                                   : Token;
HashTerm              : <INITIAL, Generic       >'#'                                                                                   : Token;
LAngleTerm            : <INITIAL, Generic       >'<'                                                                                   : Token;
QuoteLBraceTerm       : <INITIAL, Generic       >"'\{"                                                                                 : Token;
LBraceTerm            : <INITIAL, Generic, Embed>'{'                                                                                   : Token;
LBracketTerm          : <INITIAL, Generic       >'['                                                                                   : Token;
LParenTerm            : <INITIAL, Generic       >'('                                                                                   : Token;
RAngleTerm            : <INITIAL, Generic       >'>'                                                                                   : Token;
RBraceTerm            : <INITIAL, Generic, Embed>'}'                                                                                   : Token;
RBracketTerm          : <INITIAL, Generic       >']'                                                                                   : Token;
RParenTerm            : <INITIAL, Generic       >')'                                                                                   : Token;
SemicolonTerm         : <INITIAL, Generic       >';'                                                                                   : Token;
StarTerm              : <INITIAL, Generic       >'*'                                                                                   : Token;
AlwaysCombTerm        : <INITIAL, Generic       >/(?-u:\b)always_comb(?-u:\b)/                                                         : Token;
AlwaysFfTerm          : <INITIAL, Generic       >/(?-u:\b)always_ff(?-u:\b)/                                                           : Token;
AssignTerm            : <INITIAL, Generic       >/(?-u:\b)assign(?-u:\b)/                                                              : Token;
AsTerm                : <INITIAL, Generic       >/(?-u:\b)as(?-u:\b)/                                                                  : Token;
BitTerm               : <INITIAL, Generic       >/(?-u:\b)bit(?-u:\b)/                                                                 : Token;
CaseTerm              : <INITIAL, Generic       >/(?-u:\b)case(?-u:\b)/                                                                : Token;
ClockTerm             : <INITIAL, Generic       >/(?-u:\b)clock(?-u:\b)/                                                               : Token;
ClockPosedgeTerm      : <INITIAL, Generic       >/(?-u:\b)clock_posedge(?-u:\b)/                                                       : Token;
ClockNegedgeTerm      : <INITIAL, Generic       >/(?-u:\b)clock_negedge(?-u:\b)/                                                       : Token;
ConstTerm             : <INITIAL, Generic       >/(?-u:\b)const(?-u:\b)/                                                               : Token;
DefaultTerm           : <INITIAL, Generic       >/(?-u:\b)default(?-u:\b)/                                                             : Token;
ElseTerm              : <INITIAL, Generic       >/(?-u:\b)else(?-u:\b)/                                                                : Token;
EmbedTerm             : <INITIAL, Generic       >/(?-u:\b)embed(?-u:\b)/                                                               : Token;
EnumTerm              : <INITIAL, Generic       >/(?-u:\b)enum(?-u:\b)/                                                                : Token;
ExportTerm            : <INITIAL, Generic       >/(?-u:\b)export(?-u:\b)/                                                              : Token;
F32Term               : <INITIAL, Generic       >/(?-u:\b)f32(?-u:\b)/                                                                 : Token;
F64Term               : <INITIAL, Generic       >/(?-u:\b)f64(?-u:\b)/                                                                 : Token;
FinalTerm             : <INITIAL, Generic       >/(?-u:\b)final(?-u:\b)/                                                               : Token;
ForTerm               : <INITIAL, Generic       >/(?-u:\b)for(?-u:\b)/                                                                 : Token;
FunctionTerm          : <INITIAL, Generic       >/(?-u:\b)function(?-u:\b)/                                                            : Token;
I32Term               : <INITIAL, Generic       >/(?-u:\b)i32(?-u:\b)/                                                                 : Token;
I64Term               : <INITIAL, Generic       >/(?-u:\b)i64(?-u:\b)/                                                                 : Token;
IfResetTerm           : <INITIAL, Generic       >/(?-u:\b)if_reset(?-u:\b)/                                                            : Token;
IfTerm                : <INITIAL, Generic       >/(?-u:\b)if(?-u:\b)/                                                                  : Token;
ImportTerm            : <INITIAL, Generic       >/(?-u:\b)import(?-u:\b)/                                                              : Token;
IncludeTerm           : <INITIAL, Generic       >/(?-u:\b)include(?-u:\b)/                                                             : Token;
InitialTerm           : <INITIAL, Generic       >/(?-u:\b)initial(?-u:\b)/                                                             : Token;
InoutTerm             : <INITIAL, Generic       >/(?-u:\b)inout(?-u:\b)/                                                               : Token;
InputTerm             : <INITIAL, Generic       >/(?-u:\b)input(?-u:\b)/                                                               : Token;
InsideTerm            : <INITIAL, Generic       >/(?-u:\b)inside(?-u:\b)/                                                              : Token;
InstTerm              : <INITIAL, Generic       >/(?-u:\b)inst(?-u:\b)/                                                                : Token;
InterfaceTerm         : <INITIAL, Generic       >/(?-u:\b)interface(?-u:\b)/                                                           : Token;
InTerm                : <INITIAL, Generic       >/(?-u:\b)in(?-u:\b)/                                                                  : Token;
LetTerm               : <INITIAL, Generic       >/(?-u:\b)let(?-u:\b)/                                                                 : Token;
LogicTerm             : <INITIAL, Generic       >/(?-u:\b)logic(?-u:\b)/                                                               : Token;
LsbTerm               : <INITIAL, Generic       >/(?-u:\b)lsb(?-u:\b)/                                                                 : Token;
ModportTerm           : <INITIAL, Generic       >/(?-u:\b)modport(?-u:\b)/                                                             : Token;
ModuleTerm            : <INITIAL, Generic       >/(?-u:\b)module(?-u:\b)/                                                              : Token;
MsbTerm               : <INITIAL, Generic       >/(?-u:\b)msb(?-u:\b)/                                                                 : Token;
OutputTerm            : <INITIAL, Generic       >/(?-u:\b)output(?-u:\b)/                                                              : Token;
OutsideTerm           : <INITIAL, Generic       >/(?-u:\b)outside(?-u:\b)/                                                             : Token;
PackageTerm           : <INITIAL, Generic       >/(?-u:\b)package(?-u:\b)/                                                             : Token;
ParamTerm             : <INITIAL, Generic       >/(?-u:\b)param(?-u:\b)/                                                               : Token;
ProtoTerm             : <INITIAL, Generic       >/(?-u:\b)proto(?-u:\b)/                                                               : Token;
PubTerm               : <INITIAL, Generic       >/(?-u:\b)pub(?-u:\b)/                                                                 : Token;
RefTerm               : <INITIAL, Generic       >/(?-u:\b)ref(?-u:\b)/                                                                 : Token;
RepeatTerm            : <INITIAL, Generic       >/(?-u:\b)repeat(?-u:\b)/                                                              : Token;
ResetTerm             : <INITIAL, Generic       >/(?-u:\b)reset(?-u:\b)/                                                               : Token;
ResetAsyncHighTerm    : <INITIAL, Generic       >/(?-u:\b)reset_async_high(?-u:\b)/                                                    : Token;
ResetAsyncLowTerm     : <INITIAL, Generic       >/(?-u:\b)reset_async_low(?-u:\b)/                                                     : Token;
ResetSyncHighTerm     : <INITIAL, Generic       >/(?-u:\b)reset_sync_high(?-u:\b)/                                                     : Token;
ResetSyncLowTerm      : <INITIAL, Generic       >/(?-u:\b)reset_sync_low(?-u:\b)/                                                      : Token;
ReturnTerm            : <INITIAL, Generic       >/(?-u:\b)return(?-u:\b)/                                                              : Token;
BreakTerm             : <INITIAL, Generic       >/(?-u:\b)break(?-u:\b)/                                                               : Token;
SignedTerm            : <INITIAL, Generic       >/(?-u:\b)signed(?-u:\b)/                                                              : Token;
StepTerm              : <INITIAL, Generic       >/(?-u:\b)step(?-u:\b)/                                                                : Token;
StringTerm            : <INITIAL, Generic       >/(?-u:\b)string(?-u:\b)/                                                              : Token;
StructTerm            : <INITIAL, Generic       >/(?-u:\b)struct(?-u:\b)/                                                              : Token;
SwitchTerm            : <INITIAL, Generic       >/(?-u:\b)switch(?-u:\b)/                                                              : Token;
TriTerm               : <INITIAL, Generic       >/(?-u:\b)tri(?-u:\b)/                                                                 : Token;
TypeTerm              : <INITIAL, Generic       >/(?-u:\b)type(?-u:\b)/                                                                : Token;
U32Term               : <INITIAL, Generic       >/(?-u:\b)u32(?-u:\b)/                                                                 : Token;
U64Term               : <INITIAL, Generic       >/(?-u:\b)u64(?-u:\b)/                                                                 : Token;
UnionTerm             : <INITIAL, Generic       >/(?-u:\b)union(?-u:\b)/                                                               : Token;
UnsafeTerm            : <INITIAL, Generic       >/(?-u:\b)unsafe(?-u:\b)/                                                              : Token;
VarTerm               : <INITIAL, Generic       >/(?-u:\b)var(?-u:\b)/                                                                 : Token;
DollarIdentifierTerm  : <INITIAL, Generic       >/\$[a-zA-Z_][0-9a-zA-Z_$]*/                                                           : Token;
IdentifierTerm        : <INITIAL, Generic       >/(?:r#)?[a-zA-Z_][0-9a-zA-Z_$]*/                                                      : Token;
AnyTerm               : <                  Embed>/[^{}]*/                                                                              : Token;

// ----------------------------------------------------------------------------
// Token
// ----------------------------------------------------------------------------

Comments: [ CommentsTerm ];

StartToken: Comments;

StringLiteralToken: StringLiteralTerm: Token Comments;

ExponentToken  : ExponentTerm  : Token Comments;
FixedPointToken: FixedPointTerm: Token Comments;
BasedToken     : BasedTerm     : Token Comments;
BaseLessToken  : BaseLessTerm  : Token Comments;
AllBitToken    : AllBitTerm    : Token Comments;

AssignmentOperatorToken: AssignmentOperatorTerm: Token Comments;
Operator01Token        : Operator01Term        : Token Comments;
Operator02Token        : Operator02Term        : Token Comments;
Operator03Token        : Operator03Term        : Token Comments;
Operator04Token        : Operator04Term        : Token Comments;
Operator05Token        : Operator05Term        : Token Comments;
Operator06Token        : Operator06Term        : Token Comments;
Operator07Token        : Operator07Term        : Token Comments;
Operator08Token        : Operator08Term        : Token Comments;
Operator09Token        : Operator09Term        : Token Comments;
Operator10Token        : Operator10Term        : Token Comments;
Operator11Token        : Operator11Term        : Token Comments;
UnaryOperatorToken     : UnaryOperatorTerm     : Token Comments;

BackQuoteToken       : BackQuoteTerm       : Token Comments;
ColonToken           : ColonTerm           : Token Comments;
ColonColonLAngleToken: ColonColonLAngleTerm: Token Comments;
ColonColonToken      : ColonColonTerm      : Token Comments;
CommaToken           : CommaTerm           : Token Comments;
DotDotToken          : DotDotTerm          : Token Comments;
DotDotEquToken       : DotDotEquTerm       : Token Comments;
DotToken             : DotTerm             : Token Comments;
EquToken             : EquTerm             : Token Comments;
HashToken            : HashTerm            : Token Comments;
QuoteLBraceToken     : QuoteLBraceTerm     : Token Comments;
LAngleToken          : LAngleTerm          : Token Comments;
LBraceToken          : LBraceTerm          : Token Comments;
LBracketToken        : LBracketTerm        : Token Comments;
LParenToken          : LParenTerm          : Token Comments;
MinusColonToken      : MinusColonTerm      : Token Comments;
MinusGTToken         : MinusGTTerm         : Token Comments;
PlusColonToken       : PlusColonTerm       : Token Comments;
RAngleToken          : RAngleTerm          : Token Comments;
RBraceToken          : RBraceTerm          : Token Comments;
RBracketToken        : RBracketTerm        : Token Comments;
RParenToken          : RParenTerm          : Token Comments;
SemicolonToken       : SemicolonTerm       : Token Comments;
StarToken            : StarTerm            : Token Comments;

AlwaysCombToken    : AlwaysCombTerm    : Token Comments;
AlwaysFfToken      : AlwaysFfTerm      : Token Comments;
AsToken            : AsTerm            : Token Comments;
AssignToken        : AssignTerm        : Token Comments;
BitToken           : BitTerm           : Token Comments;
CaseToken          : CaseTerm          : Token Comments;
ClockToken         : ClockTerm         : Token Comments;
ClockPosedgeToken  : ClockPosedgeTerm  : Token Comments;
ClockNegedgeToken  : ClockNegedgeTerm  : Token Comments;
ConstToken         : ConstTerm         : Token Comments;
DefaultToken       : DefaultTerm       : Token Comments;
ElseToken          : ElseTerm          : Token Comments;
EmbedToken         : EmbedTerm         : Token Comments;
EnumToken          : EnumTerm          : Token Comments;
ExportToken        : ExportTerm        : Token Comments;
F32Token           : F32Term           : Token Comments;
F64Token           : F64Term           : Token Comments;
FinalToken         : FinalTerm         : Token Comments;
ForToken           : ForTerm           : Token Comments;
FunctionToken      : FunctionTerm      : Token Comments;
I32Token           : I32Term           : Token Comments;
I64Token           : I64Term           : Token Comments;
IfResetToken       : IfResetTerm       : Token Comments;
IfToken            : IfTerm            : Token Comments;
ImportToken        : ImportTerm        : Token Comments;
IncludeToken       : IncludeTerm       : Token Comments;
InitialToken       : InitialTerm       : Token Comments;
InoutToken         : InoutTerm         : Token Comments;
InputToken         : InputTerm         : Token Comments;
InsideToken        : InsideTerm        : Token Comments;
InstToken          : InstTerm          : Token Comments;
InterfaceToken     : InterfaceTerm     : Token Comments;
InToken            : InTerm            : Token Comments;
LetToken           : LetTerm           : Token Comments;
LogicToken         : LogicTerm         : Token Comments;
LsbToken           : LsbTerm           : Token Comments;
ModportToken       : ModportTerm       : Token Comments;
ModuleToken        : ModuleTerm        : Token Comments;
MsbToken           : MsbTerm           : Token Comments;
OutputToken        : OutputTerm        : Token Comments;
OutsideToken       : OutsideTerm       : Token Comments;
PackageToken       : PackageTerm       : Token Comments;
ParamToken         : ParamTerm         : Token Comments;
ProtoToken         : ProtoTerm         : Token Comments;
PubToken           : PubTerm           : Token Comments;
RefToken           : RefTerm           : Token Comments;
RepeatToken        : RepeatTerm        : Token Comments;
ResetToken         : ResetTerm         : Token Comments;
ResetAsyncHighToken: ResetAsyncHighTerm: Token Comments;
ResetAsyncLowToken : ResetAsyncLowTerm : Token Comments;
ResetSyncHighToken : ResetSyncHighTerm : Token Comments;
ResetSyncLowToken  : ResetSyncLowTerm  : Token Comments;
ReturnToken        : ReturnTerm        : Token Comments;
BreakToken         : BreakTerm         : Token Comments;
SignedToken        : SignedTerm        : Token Comments;
StepToken          : StepTerm          : Token Comments;
StringToken        : StringTerm        : Token Comments;
StructToken        : StructTerm        : Token Comments;
SwitchToken        : SwitchTerm        : Token Comments;
TriToken           : TriTerm           : Token Comments;
TypeToken          : TypeTerm          : Token Comments;
U32Token           : U32Term           : Token Comments;
U64Token           : U64Term           : Token Comments;
UnionToken         : UnionTerm         : Token Comments;
UnsafeToken        : UnsafeTerm        : Token Comments;
VarToken           : VarTerm           : Token Comments;

DollarIdentifierToken: DollarIdentifierTerm: Token Comments;
IdentifierToken      : IdentifierTerm      : Token Comments;

// ----------------------------------------------------------------------------
// VerylToken
// ----------------------------------------------------------------------------

// Start
Start: StartToken: VerylToken;

// StringLiteral
StringLiteral: StringLiteralToken: VerylToken;

// Number
Exponent  : ExponentToken  : VerylToken;
FixedPoint: FixedPointToken: VerylToken;
Based     : BasedToken     : VerylToken;
BaseLess  : BaseLessToken  : VerylToken;
AllBit    : AllBitToken    : VerylToken;

// Operator
AssignmentOperator: AssignmentOperatorToken: VerylToken;
Operator01        : Operator01Token        : VerylToken;
Operator02        : Operator02Token        : VerylToken;
Operator03        : Operator03Token        : VerylToken;
Operator04        : Operator04Token        : VerylToken;
Operator05        : Operator05Token        : VerylToken;
Operator06        : Operator06Token        : VerylToken;
Operator07        : Operator07Token        : VerylToken;
Operator08        : Operator08Token        : VerylToken;
Operator09        : Operator09Token        : VerylToken;
Operator10        : Operator10Token        : VerylToken;
Operator11        : Operator11Token        : VerylToken;
UnaryOperator     : UnaryOperatorToken     : VerylToken;

// Symbol
BackQuote       : BackQuoteToken       : VerylToken;
Colon           : ColonToken           : VerylToken;
ColonColonLAngle: ColonColonLAngleToken: VerylToken;
ColonColon      : ColonColonToken      : VerylToken;
Comma           : CommaToken           : VerylToken;
DotDot          : DotDotToken          : VerylToken;
DotDotEqu       : DotDotEquToken       : VerylToken;
Dot             : DotToken             : VerylToken;
Equ             : EquToken             : VerylToken;
Hash            : HashToken            : VerylToken;
QuoteLBrace     : QuoteLBraceToken     : VerylToken;
LAngle          : LAngleToken          : VerylToken;
LBrace          : LBraceToken          : VerylToken;
LBracket        : LBracketToken        : VerylToken;
LParen          : LParenToken          : VerylToken;
MinusColon      : MinusColonToken      : VerylToken;
MinusGT         : MinusGTToken         : VerylToken;
PlusColon       : PlusColonToken       : VerylToken;
RAngle          : RAngleToken          : VerylToken;
RBrace          : RBraceToken          : VerylToken;
RBracket        : RBracketToken        : VerylToken;
RParen          : RParenToken          : VerylToken;
Semicolon       : SemicolonToken       : VerylToken;
Star            : StarToken            : VerylToken;

// Keyword
AlwaysComb    : AlwaysCombToken    : VerylToken;
AlwaysFf      : AlwaysFfToken      : VerylToken;
As            : AsToken            : VerylToken;
Assign        : AssignToken        : VerylToken;
Bit           : BitToken           : VerylToken;
Break         : BreakToken         : VerylToken;
Case          : CaseToken          : VerylToken;
Clock         : ClockToken         : VerylToken;
ClockPosedge  : ClockPosedgeToken  : VerylToken;
ClockNegedge  : ClockNegedgeToken  : VerylToken;
Const         : ConstToken         : VerylToken;
Defaul        : DefaultToken       : VerylToken; // avoid to conflict with Rust's Default trait
Else          : ElseToken          : VerylToken;
Embed         : EmbedToken         : VerylToken;
Enum          : EnumToken          : VerylToken;
Export        : ExportToken        : VerylToken;
F32           : F32Token           : VerylToken;
F64           : F64Token           : VerylToken;
Final         : FinalToken         : VerylToken;
For           : ForToken           : VerylToken;
Function      : FunctionToken      : VerylToken;
I32           : I32Token           : VerylToken;
I64           : I64Token           : VerylToken;
If            : IfToken            : VerylToken;
IfReset       : IfResetToken       : VerylToken;
Import        : ImportToken        : VerylToken;
In            : InToken            : VerylToken;
Include       : IncludeToken       : VerylToken;
Initial       : InitialToken       : VerylToken;
Inout         : InoutToken         : VerylToken;
Input         : InputToken         : VerylToken;
Inside        : InsideToken        : VerylToken;
Inst          : InstToken          : VerylToken;
Interface     : InterfaceToken     : VerylToken;
Let           : LetToken           : VerylToken;
Logic         : LogicToken         : VerylToken;
Lsb           : LsbToken           : VerylToken;
Modport       : ModportToken       : VerylToken;
Module        : ModuleToken        : VerylToken;
Msb           : MsbToken           : VerylToken;
Output        : OutputToken        : VerylToken;
Outside       : OutsideToken       : VerylToken;
Package       : PackageToken       : VerylToken;
Param         : ParamToken         : VerylToken;
Proto         : ProtoToken         : VerylToken;
Pub           : PubToken           : VerylToken;
Ref           : RefToken           : VerylToken;
Repeat        : RepeatToken        : VerylToken;
Reset         : ResetToken         : VerylToken;
ResetAsyncHigh: ResetAsyncHighToken: VerylToken;
ResetAsyncLow : ResetAsyncLowToken : VerylToken;
ResetSyncHigh : ResetSyncHighToken : VerylToken;
ResetSyncLow  : ResetSyncLowToken  : VerylToken;
Return        : ReturnToken        : VerylToken;
Signed        : SignedToken        : VerylToken;
Step          : StepToken          : VerylToken;
Strin         : StringToken        : VerylToken; // avoid to conflict with Rust's String struct
Struct        : StructToken        : VerylToken;
Switch        : SwitchToken        : VerylToken;
Tri           : TriToken           : VerylToken;
Type          : TypeToken          : VerylToken;
U32           : U32Token           : VerylToken;
U64           : U64Token           : VerylToken;
Union         : UnionToken         : VerylToken;
Unsafe        : UnsafeToken        : VerylToken;
Var           : VarToken           : VerylToken;

// Identifier
DollarIdentifier: DollarIdentifierToken: VerylToken;
Identifier      : IdentifierToken      : VerylToken;

// ----------------------------------------------------------------------------
// Number
// ----------------------------------------------------------------------------

Number: IntegralNumber
      | RealNumber
      ;

IntegralNumber: Based
              | BaseLess
              | AllBit
              ;

RealNumber: FixedPoint
          | Exponent
          ;

// ----------------------------------------------------------------------------
// Complex Identifier
// ----------------------------------------------------------------------------

HierarchicalIdentifier: Identifier { Select } { Dot Identifier { Select } };
ScopedIdentifier      : ( DollarIdentifier | Identifier [ WithGenericArgument ] ) { ColonColon Identifier [ WithGenericArgument ] };
ExpressionIdentifier  : ScopedIdentifier [ Width ] { Select } { Dot Identifier { Select } };

// ----------------------------------------------------------------------------
// Expression
// ----------------------------------------------------------------------------

Expression  : Expression01 { Operator01 Expression01 };
Expression01: Expression02 { Operator02 Expression02 };
Expression02: Expression03 { Operator03 Expression03 };
Expression03: Expression04 { Operator04 Expression04 };
Expression04: Expression05 { Operator05 Expression05 };
Expression05: Expression06 { Operator06 Expression06 };
Expression06: Expression07 { Operator07 Expression07 };
Expression07: Expression08 { Operator08 Expression08 };
Expression08: Expression09 { Operator09 Expression09 };
Expression09: Expression10 { ( Operator10 | Star ) Expression10 };
Expression10: Expression11 { Operator11 Expression11 };
Expression11: Expression12 [ As CastingType ];
Expression12: { ( UnaryOperator | Operator09 | Operator05 | Operator03 | Operator04 ) } Factor;

Factor: Number
      | ExpressionIdentifier [ FunctionCall ]
      | LParen Expression RParen
      | LBrace ConcatenationList RBrace
      | QuoteLBrace ArrayLiteralList RBrace
      | IfExpression
      | CaseExpression
      | SwitchExpression
      | StringLiteral
      | ( Msb | Lsb )
      | InsideExpression
      | OutsideExpression
      | TypeExpression
      | FactorType
      ;

FunctionCall: LParen [ ArgumentList ] RParen;

ArgumentList: ArgumentItem { Comma ArgumentItem } [ Comma ];

ArgumentItem: Expression;

ConcatenationList: ConcatenationItem { Comma ConcatenationItem } [ Comma ];

ConcatenationItem: Expression [ Repeat Expression ];

ArrayLiteralList: ArrayLiteralItem { Comma ArrayLiteralItem } [ Comma ];

ArrayLiteralItem: ( Expression [ Repeat Expression ] | Defaul Colon Expression );

IfExpression: If Expression LBrace Expression RBrace { Else If Expression LBrace Expression RBrace } Else LBrace Expression RBrace;

CaseExpression: Case Expression LBrace CaseCondition Colon Expression Comma { CaseCondition Colon Expression Comma } Defaul Colon Expression [ Comma ] RBrace;

SwitchExpression: Switch LBrace SwitchCondition Colon Expression Comma { SwitchCondition Colon Expression Comma } Defaul Colon Expression [ Comma ] RBrace;

TypeExpression: Type LParen Expression RParen;

InsideExpression: Inside Expression LBrace RangeList RBrace;

OutsideExpression: Outside Expression LBrace RangeList RBrace;

RangeList: RangeItem { Comma RangeItem } [ Comma ];

RangeItem: Range;

// ----------------------------------------------------------------------------
// Select / Width / Array / Range
// ----------------------------------------------------------------------------

Select: LBracket Expression [ SelectOperator Expression ] RBracket;

SelectOperator: Colon
              | PlusColon
              | MinusColon
              | Step
              ;

Width: LAngle Expression { Comma Expression } RAngle;

Array: LBracket Expression { Comma Expression } RBracket;

Range: Expression [ RangeOperator Expression ];

RangeOperator: DotDot
             | DotDotEqu
             ;

// ----------------------------------------------------------------------------
// ScalarType / ArrayType / CastingType
// ----------------------------------------------------------------------------

FixedType: U32 | U64 | I32 | I64 | F32 | F64 | Strin;

VariableType: Clock
            | ClockPosedge
            | ClockNegedge
            | Reset
            | ResetAsyncHigh
            | ResetAsyncLow
            | ResetSyncHigh
            | ResetSyncLow
            | Logic
            | Bit;

UserDefinedType: ScopedIdentifier;

TypeModifier: Tri | Signed;

FactorType: ( VariableType [ Width ] | FixedType );

ScalarType: { TypeModifier } ( UserDefinedType [ Width ] | FactorType );

ArrayType: ScalarType [ Array ];

CastingType: U32
           | U64
           | I32
           | I64
           | F32
           | F64
           | Clock
           | ClockPosedge
           | ClockNegedge
           | Reset
           | ResetAsyncHigh
           | ResetAsyncLow
           | ResetSyncHigh
           | ResetSyncLow
           | UserDefinedType
           ;

// ----------------------------------------------------------------------------
// ClockDomain
// ----------------------------------------------------------------------------

ClockDomain: BackQuote Identifier;

// ----------------------------------------------------------------------------
// Statement
// ----------------------------------------------------------------------------

StatementBlock: LBrace { StatementBlockItem } RBrace;

StatementBlockItem: VarDeclaration | LetStatement | Statement;

Statement: IdentifierStatement
         | IfStatement
         | IfResetStatement
         | ReturnStatement
         | BreakStatement
         | ForStatement
         | CaseStatement
         | SwitchStatement
         ;

LetStatement: Let Identifier Colon [ ClockDomain ] ArrayType Equ Expression Semicolon;

IdentifierStatement: ExpressionIdentifier ( FunctionCall | Assignment ) Semicolon;

Assignment: ( Equ | AssignmentOperator ) Expression;

IfStatement: If Expression StatementBlock { Else If Expression StatementBlock } [ Else StatementBlock ];

IfResetStatement: IfReset StatementBlock { Else If Expression StatementBlock } [ Else StatementBlock ];

ReturnStatement: Return Expression Semicolon;

BreakStatement: Break Semicolon;

ForStatement: For Identifier Colon ScalarType In Range [ Step AssignmentOperator Expression ] StatementBlock;

CaseStatement: Case Expression LBrace { CaseItem } RBrace;

CaseItem: ( CaseCondition | Defaul ) Colon ( Statement | StatementBlock );

CaseCondition: RangeItem { Comma RangeItem } ;

SwitchStatement: Switch LBrace { SwitchItem } RBrace;

SwitchItem: ( SwitchCondition | Defaul ) Colon ( Statement | StatementBlock );

SwitchCondition: Expression { Comma Expression } ;

// ----------------------------------------------------------------------------
// Attribute
// ----------------------------------------------------------------------------

Attribute: Hash LBracket Identifier [ LParen AttributeList RParen ] RBracket;

AttributeList: AttributeItem { Comma AttributeItem } [ Comma ];

AttributeItem: Identifier
             | StringLiteral
             ;

// ----------------------------------------------------------------------------
// Declaration
// ----------------------------------------------------------------------------

LetDeclaration: Let Identifier Colon [ ClockDomain ] ArrayType Equ Expression Semicolon;

VarDeclaration: Var Identifier Colon [ ClockDomain ] ArrayType Semicolon;

ConstDeclaration: Const Identifier Colon ( ArrayType | Type ) Equ Expression Semicolon;

TypeDefDeclaration: Type Identifier Equ ArrayType Semicolon;

AlwaysFfDeclaration: AlwaysFf [ AlwayfFfEventList ] StatementBlock;

AlwayfFfEventList: LParen AlwaysFfClock [ Comma AlwaysFfReset ] RParen;

AlwaysFfClock: HierarchicalIdentifier;

AlwaysFfReset: HierarchicalIdentifier;

AlwaysCombDeclaration: AlwaysComb StatementBlock;

AssignDeclaration: Assign HierarchicalIdentifier Equ Expression Semicolon;

ModportDeclaration: Modport Identifier LBrace ModportList RBrace;

ModportList: ModportGroup { Comma ModportGroup } [ Comma ];

ModportGroup: { Attribute } ( LBrace ModportList RBrace | ModportItem );

ModportItem: Identifier Colon Direction;

EnumDeclaration: Enum Identifier [ Colon ScalarType ] LBrace EnumList RBrace;

EnumList: EnumGroup { Comma EnumGroup } [ Comma ];

EnumGroup: { Attribute } ( LBrace EnumList RBrace | EnumItem );

EnumItem: Identifier [ Equ Expression ];

StructUnion: Struct | Union;

StructUnionDeclaration: StructUnion Identifier [ WithGenericParameter ] LBrace StructUnionList RBrace;

StructUnionList: StructUnionGroup { Comma StructUnionGroup } [ Comma ];

StructUnionGroup: { Attribute } ( LBrace StructUnionList RBrace | StructUnionItem );

StructUnionItem: Identifier Colon ScalarType;

InitialDeclaration: Initial StatementBlock;

FinalDeclaration: Final StatementBlock;

// ----------------------------------------------------------------------------
// InstDeclaration
// ----------------------------------------------------------------------------

InstDeclaration: Inst Identifier Colon ScopedIdentifier [ Array ] [ InstParameter ] [ LParen [ InstPortList ] RParen ] Semicolon;

InstParameter: Hash LParen [ InstParameterList ] RParen;

InstParameterList: InstParameterGroup { Comma InstParameterGroup } [ Comma ];

InstParameterGroup: { Attribute } ( LBrace InstParameterList RBrace | InstParameterItem );

InstParameterItem: Identifier [ Colon Expression ];

InstPortList: InstPortGroup { Comma InstPortGroup } [ Comma ];

InstPortGroup: { Attribute } ( LBrace InstPortList RBrace | InstPortItem );

InstPortItem: Identifier [ Colon Expression ];

// ----------------------------------------------------------------------------
// WithParameter
// ----------------------------------------------------------------------------

WithParameter: Hash LParen [ WithParameterList ] RParen;

WithParameterList: WithParameterGroup { Comma WithParameterGroup } [ Comma ];

WithParameterGroup: { Attribute } ( LBrace WithParameterList RBrace | WithParameterItem );

WithParameterItem: ( Param | Const ) Identifier Colon ( ArrayType | Type ) Equ Expression;

// ----------------------------------------------------------------------------
// WithGenericParameter
// ----------------------------------------------------------------------------

GenericBound: Const
            | Type
            | ScopedIdentifier;

WithGenericParameter: ColonColonLAngle WithGenericParameterList RAngle;

WithGenericParameterList: WithGenericParameterItem { Comma WithGenericParameterItem } [ Comma ];

WithGenericParameterItem: Identifier Colon GenericBound [ Equ WithGenericArgumentItem ];

// ----------------------------------------------------------------------------
// WithGenericArgument
// ----------------------------------------------------------------------------

WithGenericArgument: ColonColonLAngle %push(Generic) [ WithGenericArgumentList ] RAngle %pop();

WithGenericArgumentList: WithGenericArgumentItem { Comma WithGenericArgumentItem } [ Comma ];

WithGenericArgumentItem: ScopedIdentifier
                       | Number
                       ;

// ----------------------------------------------------------------------------
// PortDeclaration
// ----------------------------------------------------------------------------

PortDeclaration: LParen [ PortDeclarationList ] RParen;

PortDeclarationList: PortDeclarationGroup { Comma PortDeclarationGroup } [ Comma ];

PortDeclarationGroup: { Attribute } ( LBrace PortDeclarationList RBrace | PortDeclarationItem );

PortDeclarationItem: Identifier Colon ( PortTypeConcrete | PortTypeAbstract );

PortTypeConcrete: Direction [ ClockDomain ] ArrayType;

PortTypeAbstract: [ ClockDomain ] Interface [ Array ];

Direction: Input
         | Output
         | Inout
         | Ref
         | Modport
         | Import
         ;

// ----------------------------------------------------------------------------
// Function
// ----------------------------------------------------------------------------

FunctionDeclaration: Function Identifier [ WithGenericParameter ] [ PortDeclaration ] [ MinusGT ScalarType ] StatementBlock;

// ----------------------------------------------------------------------------
// Import / Export
// ----------------------------------------------------------------------------

ImportDeclaration: Import ScopedIdentifier [ ColonColon Star ] Semicolon;

ExportDeclaration: Export ( Star | ScopedIdentifier [ ColonColon Star ] ) Semicolon;

// ----------------------------------------------------------------------------
// Unsafe
// ----------------------------------------------------------------------------

UnsafeBlock: Unsafe LParen Identifier RParen LBrace { GenerateGroup } RBrace;

// ----------------------------------------------------------------------------
// Module/Interface
// ----------------------------------------------------------------------------

ModuleDeclaration: [ Pub ] Module Identifier [ WithGenericParameter ] [ For ScopedIdentifier ] [ WithParameter ] [ PortDeclaration ] LBrace { ModuleGroup } RBrace;

ModuleGroup: { Attribute } ( LBrace { ModuleGroup } RBrace | ModuleItem );

ModuleItem: GenerateItem;

InterfaceDeclaration: [ Pub ] Interface Identifier [ WithGenericParameter ] [ WithParameter ] LBrace { InterfaceGroup } RBrace;

InterfaceGroup: { Attribute } ( LBrace { InterfaceGroup } RBrace | InterfaceItem );

InterfaceItem: GenerateItem | ModportDeclaration;

GenerateIfDeclaration: If Expression GenerateNamedBlock { Else If Expression GenerateOptionalNamedBlock } [ Else GenerateOptionalNamedBlock ];

GenerateForDeclaration: For Identifier In Range [ Step AssignmentOperator Expression ] GenerateNamedBlock;

GenerateBlockDeclaration: GenerateNamedBlock;

GenerateNamedBlock: Colon Identifier LBrace { GenerateGroup } RBrace;

GenerateOptionalNamedBlock: [ Colon Identifier ] LBrace { GenerateGroup } RBrace;

GenerateGroup: { Attribute } ( LBrace { GenerateGroup } RBrace | GenerateItem );

GenerateItem: LetDeclaration
            | VarDeclaration
            | InstDeclaration
            | ConstDeclaration
            | AlwaysFfDeclaration
            | AlwaysCombDeclaration
            | AssignDeclaration
            | FunctionDeclaration
            | GenerateIfDeclaration
            | GenerateForDeclaration
            | GenerateBlockDeclaration
            | TypeDefDeclaration
            | EnumDeclaration
            | StructUnionDeclaration
            | ImportDeclaration
            | InitialDeclaration
            | FinalDeclaration
            | UnsafeBlock
            ;

// ----------------------------------------------------------------------------
// Package
// ----------------------------------------------------------------------------

PackageDeclaration: [ Pub ] Package Identifier [ WithGenericParameter ] LBrace { PackageGroup } RBrace;

PackageGroup: { Attribute } ( LBrace { PackageGroup } RBrace | PackageItem );

PackageItem: VarDeclaration
           | ConstDeclaration
           | TypeDefDeclaration
           | EnumDeclaration
           | StructUnionDeclaration
           | FunctionDeclaration
           | ImportDeclaration
           | ExportDeclaration
           ;

// ----------------------------------------------------------------------------
// Proto
// ----------------------------------------------------------------------------

ProtoModuleDeclaration: [ Pub ] Proto Module Identifier [ WithParameter ] [ PortDeclaration ] Semicolon;

// ----------------------------------------------------------------------------
// Embed
// ----------------------------------------------------------------------------

EmbedDeclaration: Embed LParen Identifier RParen Identifier EmbedContent;

EmbedContent: EmbedContentToken: VerylToken;

EmbedContentToken: LBraceTerm %push(Embed) LBraceTerm LBraceTerm { EmbedItem } RBraceTerm RBraceTerm RBraceTerm %pop() Comments;

EmbedItem: LBraceTerm { EmbedItem } RBraceTerm
         | AnyTerm;

// ----------------------------------------------------------------------------
// Include
// ----------------------------------------------------------------------------

IncludeDeclaration: Include LParen Identifier Comma StringLiteral RParen Semicolon;

// ----------------------------------------------------------------------------
// Description
// ----------------------------------------------------------------------------

DescriptionGroup: { Attribute } ( LBrace { DescriptionGroup } RBrace | DescriptionItem );

DescriptionItem: ModuleDeclaration
               | InterfaceDeclaration
               | PackageDeclaration
               | ProtoModuleDeclaration
               | ImportDeclaration
               | EmbedDeclaration
               | IncludeDeclaration
               ;

// ----------------------------------------------------------------------------
// SourceCode
// ----------------------------------------------------------------------------

Veryl: Start { DescriptionGroup };