|
@dialects { jsx, ts } |
|
|
|
@precedence { |
|
typeargs, |
|
typeMember, |
|
typePrefix, |
|
intersectionPrefixed @left, |
|
intersection @left, |
|
unionPrefixed @left, |
|
union @left, |
|
typeExtends @right, |
|
else @right, |
|
member, |
|
readonly, |
|
newArgs, |
|
call, |
|
instantiate, |
|
taggedTemplate, |
|
prefix, |
|
postfix, |
|
typeof, |
|
exp @left, |
|
times @left, |
|
plus @left, |
|
shift @left, |
|
loop, |
|
rel @left, |
|
satisfies, |
|
equal @left, |
|
bitAnd @left, |
|
bitXor @left, |
|
bitOr @left, |
|
and @left, |
|
or @left, |
|
ternary @right, |
|
assign @right, |
|
comma @left, |
|
statement @cut, |
|
predicate |
|
} |
|
|
|
@top Script { Hashbang? statement+ } |
|
|
|
@top SingleExpression { expression } |
|
|
|
@top SingleClassItem { classItem } |
|
|
|
statement[@isGroup=Statement] { |
|
ExportDeclaration | |
|
ImportDeclaration | |
|
ForStatement { kw<"for"> ckw<"await">? (ForSpec | ForInSpec | ForOfSpec) statement } | |
|
WhileStatement { kw<"while"> ParenthesizedExpression statement } | |
|
WithStatement { kw<"with"> ParenthesizedExpression statement } | |
|
DoStatement { kw<"do"> statement kw<"while"> ParenthesizedExpression semi } | |
|
IfStatement { kw<"if"> ParenthesizedExpression statement (!else kw<"else"> statement)? } | |
|
SwitchStatement { kw<"switch"> ParenthesizedExpression SwitchBody { "{" switchItem* "}" } } | |
|
TryStatement { |
|
kw<"try"> Block |
|
CatchClause { kw<"catch"> ("(" pattern ")")? Block }? |
|
FinallyClause { kw<"finally"> Block }? |
|
} | |
|
ReturnStatement { kw<"return"> (noSemi expression)? semi } | |
|
ThrowStatement { kw<"throw"> expression semi } | |
|
BreakStatement { kw<"break"> (noSemi Label)? semi } | |
|
ContinueStatement { kw<"continue"> (noSemi Label)? semi } | |
|
DebuggerStatement { kw<"debugger"> semi } | |
|
Block | |
|
LabeledStatement { Label ":" statement } | |
|
declaration | |
|
ExpressionStatement { expression semi } | |
|
";" |
|
} |
|
|
|
ExportDeclaration { |
|
kw<"export"> Star (ckw<"as"> (VariableName | String))? ckw<"from"> String semi | |
|
kw<"export"> kw<"default"> (FunctionDeclaration | ClassDeclaration | expression semi) | |
|
kw<"export"> tskw<"type">? declaration | |
|
kw<"export"> tskw<"type">? ExportGroup (ckw<"from"> String)? semi | |
|
kw<"export"> "=" expression semi |
|
} |
|
|
|
ExportGroup { |
|
"{" commaSep<(VariableName | String | kw<"default">) (ckw<"as"> (VariableName { word } | String))?> "}" |
|
} |
|
|
|
ImportDeclaration { |
|
kw<"import"> tskw<"type">? (Star ckw<"as"> VariableDefinition | commaSep<VariableDefinition | ImportGroup>) |
|
ckw<"from"> String semi | |
|
kw<"import"> String semi |
|
} |
|
|
|
ImportGroup { |
|
"{" commaSep<tskw<"type">? (VariableDefinition | (VariableName | String | kw<"default">) ckw<"as"> VariableDefinition)> "}" |
|
} |
|
|
|
ForSpec { |
|
"(" |
|
(VariableDeclaration | expression ";" | ";") expression? ";" expression? |
|
")" |
|
} |
|
|
|
forXSpec<op> { |
|
"(" |
|
(variableDeclarationKeyword pattern | VariableName | MemberExpression | ArrayPattern | ObjectPattern) |
|
!loop op expression |
|
")" |
|
} |
|
|
|
ForInSpec { forXSpec<kw<"in">> } |
|
ForOfSpec { forXSpec<ckw<"of">> } |
|
|
|
declaration { |
|
FunctionDeclaration | |
|
ClassDeclaration | |
|
VariableDeclaration | |
|
TypeAliasDeclaration | |
|
InterfaceDeclaration | |
|
EnumDeclaration | |
|
NamespaceDeclaration | |
|
AmbientDeclaration |
|
} |
|
|
|
FunctionDeclaration { |
|
async? !statement kw<"function"> Star? VariableDefinition? functionSignature (Block | semi) |
|
} |
|
|
|
ClassDeclaration { |
|
!statement Decorator* tskw<"abstract">? kw<"class"> VariableDefinition TypeParamList? |
|
(kw<"extends"> ((VariableName | MemberExpression) !typeargs TypeArgList | expression))? |
|
(tskw<"implements"> commaSep1<type>)? |
|
ClassBody |
|
} |
|
|
|
classItem { MethodDeclaration | PropertyDeclaration | StaticBlock | ";" } |
|
|
|
ClassBody { "{" classItem* "}" } |
|
|
|
privacy { |
|
@extend[@name=Privacy,@dialect=ts]<word, "public" | "private" | "protected"> |
|
} |
|
|
|
privacyArg { |
|
@extend[@name=Privacy,@dialect=ts]<identifier, "public" | "private" | "protected"> |
|
} |
|
|
|
propModifier { |
|
Decorator | |
|
tsPkwMod<"declare"> | |
|
privacy | |
|
pkwMod<"static"> | |
|
tsPkwMod<"abstract"> | |
|
tsPkwMod<"override"> |
|
} |
|
|
|
classPropName { propName | PrivatePropertyDefinition } |
|
|
|
MethodDeclaration[group=ClassItem] { |
|
propModifier* |
|
pkwMod<"async">? |
|
(pkwMod<"get"> | pkwMod<"set"> | Star)? |
|
classPropName |
|
functionSignature |
|
(Block | semi) |
|
} |
|
|
|
StaticBlock[group=ClassItem] { |
|
pkwMod<"static"> Block |
|
} |
|
|
|
PropertyDeclaration[group=ClassItem] { |
|
propModifier* |
|
(tsPkwMod<"readonly"> | pkwMod<"accessor">)? |
|
classPropName |
|
(Optional | LogicOp<"!">)? |
|
TypeAnnotation? |
|
("=" expressionNoComma)? |
|
semi |
|
} |
|
|
|
variableDeclarationKeyword { |
|
kw<"let"> | kw<"var"> | kw<"const"> | ckw<"await">? ckw<"using"> |
|
} |
|
|
|
VariableDeclaration { |
|
variableDeclarationKeyword commaSep1<patternAssignTyped> semi |
|
} |
|
|
|
TypeAliasDeclaration { |
|
tskw<"type"> TypeDefinition TypeParamList? "=" type semi |
|
} |
|
|
|
InterfaceDeclaration { |
|
tskw<"interface"> TypeDefinition TypeParamList? (kw<"extends"> type)? ObjectType |
|
} |
|
|
|
EnumDeclaration { |
|
kw<"const">? tskw<"enum"> TypeDefinition EnumBody { "{" commaSep<PropertyName ("=" expressionNoComma)?> "}" } |
|
} |
|
|
|
NamespaceDeclaration { |
|
(tskw<"namespace"> | tskw<"module">) VariableDefinition ("." PropertyDefinition)* Block |
|
} |
|
|
|
AmbientDeclaration { |
|
tskw<"declare"> ( |
|
VariableDeclaration | |
|
TypeAliasDeclaration | |
|
EnumDeclaration | |
|
InterfaceDeclaration | |
|
NamespaceDeclaration | |
|
GlobalDeclaration { tskw<"global"> Block } | |
|
ClassDeclaration { |
|
tskw<"abstract">? kw<"class"> VariableDefinition TypeParamList? |
|
(kw<"extends"> expression)? |
|
(tskw<"implements"> commaSep1<type>)? |
|
ClassBody { "{" ( |
|
MethodDeclaration | |
|
PropertyDeclaration | |
|
IndexSignature semi |
|
)* "}" } |
|
} | |
|
AmbientFunctionDeclaration { |
|
async? kw<"function"> Star? VariableDefinition? TypeParamList? ParamList (TypeAnnotation | TypePredicate) semi |
|
} |
|
) |
|
} |
|
|
|
decoratorExpression { |
|
VariableName | |
|
MemberExpression { decoratorExpression !member ("." | questionDot) (PropertyName | PrivatePropertyName) } | |
|
CallExpression { decoratorExpression !call TypeArgList? questionDot? ArgList } | |
|
ParenthesizedExpression |
|
} |
|
|
|
Decorator { "@" decoratorExpression } |
|
|
|
pattern { VariableDefinition | ArrayPattern | ObjectPattern } |
|
|
|
ArrayPattern { "[" commaSep<("..."? patternAssign)?> ~destructure "]" } |
|
|
|
ObjectPattern { "{" commaSep<PatternProperty> ~destructure "}" } |
|
|
|
patternAssign { |
|
pattern ("=" expressionNoComma)? |
|
} |
|
|
|
TypeAnnotation { ":" type } |
|
|
|
TypePredicate { ":" (VariableName | kw<"this">) !predicate tskw<"is"> type } |
|
|
|
patternAssignTyped { |
|
pattern Optional? TypeAnnotation? ("=" expressionNoComma)? |
|
} |
|
|
|
ParamList { |
|
"(" commaSep<"..." patternAssignTyped | Decorator* privacyArg? tskw<"readonly">? patternAssignTyped | kw<"this"> TypeAnnotation> ")" |
|
} |
|
|
|
Block { |
|
!statement "{" statement* "}" |
|
} |
|
|
|
switchItem { |
|
CaseLabel { kw<"case"> expression ":" } | |
|
DefaultLabel { kw<"default"> ":" } | |
|
statement |
|
} |
|
|
|
expression[@isGroup=Expression] { |
|
expressionNoComma | SequenceExpression |
|
} |
|
|
|
SequenceExpression { |
|
expressionNoComma !comma ("," expressionNoComma)+ |
|
} |
|
|
|
expressionNoComma { |
|
Number | |
|
String | |
|
TemplateString | |
|
VariableName | |
|
boolean | |
|
kw<"this"> | |
|
kw<"null"> | |
|
kw<"super"> | |
|
RegExp | |
|
ArrayExpression | |
|
ObjectExpression { "{" commaSep<Property> ~destructure "}" } | |
|
NewTarget { kw<"new"> "." PropertyName } | |
|
NewExpression { kw<"new"> expressionNoComma (!newArgs ArgList)? } | |
|
UnaryExpression | |
|
YieldExpression | |
|
AwaitExpression | |
|
ParenthesizedExpression | |
|
ClassExpression | |
|
FunctionExpression | |
|
ArrowFunction | |
|
MemberExpression | |
|
BinaryExpression | |
|
ConditionalExpression { expressionNoComma !ternary questionOp expressionNoComma LogicOp<":"> expressionNoComma } | |
|
AssignmentExpression | |
|
PostfixExpression { expressionNoComma !postfix (incdec | LogicOp<"!">) } | |
|
CallExpression { expressionNoComma !call questionDot? ArgList } | |
|
InstantiationExpression { (VariableName | MemberExpression) !instantiate TypeArgList } | |
|
TaggedTemplateExpression { expressionNoComma !taggedTemplate TemplateString } | |
|
DynamicImport { kw<"import"> "(" expressionNoComma ")" } | |
|
ImportMeta { kw<"import"> "." PropertyName } | |
|
JSXElement | |
|
PrefixCast { tsAngleOpen type ~tsAngle ">" expressionNoComma } | |
|
ArrowFunction[@dynamicPrecedence=1] { |
|
TypeParamList { tsAngleOpen commaSep<typeParam> ">" } ParamList TypeAnnotation? "=>" (Block | expressionNoComma) |
|
} |
|
} |
|
|
|
ParenthesizedExpression { "(" expression ")" } |
|
|
|
ArrayExpression { |
|
"[" commaSep1<"..."? expressionNoComma | ""> ~destructure "]" |
|
} |
|
|
|
propName { PropertyDefinition | "[" expression "]" | Number | String } |
|
|
|
Property { |
|
pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? propName functionSignature Block | |
|
propName ~destructure (":" expressionNoComma)? | |
|
"..." expressionNoComma |
|
} |
|
|
|
PatternProperty { |
|
"..." patternAssign | |
|
((PropertyName | Number | String) ~destructure (":" pattern)? | |
|
("[" expression "]" ~destructure ":" pattern)) ("=" expressionNoComma)? |
|
} |
|
|
|
ClassExpression { |
|
kw<"class"> VariableDefinition? (kw<"extends"> expression)? ClassBody |
|
} |
|
|
|
functionSignature { TypeParamList? ParamList (TypeAnnotation | TypePredicate)? } |
|
|
|
FunctionExpression { |
|
async? kw<"function"> Star? VariableDefinition? functionSignature Block |
|
} |
|
|
|
YieldExpression[@dynamicPrecedence=1] { |
|
!prefix ckw<"yield"> Star? expressionNoComma |
|
} |
|
|
|
AwaitExpression[@dynamicPrecedence=1] { |
|
!prefix ckw<"await"> expressionNoComma |
|
} |
|
|
|
UnaryExpression { |
|
!prefix (kw<"void"> | kw<"typeof"> | kw<"delete"> | |
|
LogicOp<"!"> | BitOp<"~"> | incdec | incdecPrefix | ArithOp<"+" | "-">) |
|
expressionNoComma |
|
} |
|
|
|
BinaryExpression { |
|
expressionNoComma !exp ArithOp<"**"> expressionNoComma | |
|
expressionNoComma !times (divide | ArithOp<"%"> | ArithOp<"*">) expressionNoComma | |
|
expressionNoComma !plus ArithOp<"+" | "-"> expressionNoComma | |
|
expressionNoComma !shift BitOp<">>" ">"? | "<<"> expressionNoComma | |
|
expressionNoComma !rel (LessThan | CompareOp<"<=" | ">" "="?> | kw<"instanceof">) expressionNoComma | |
|
expressionNoComma !satisfies tskw<"satisfies"> type | |
|
(expressionNoComma | PrivatePropertyName) !rel ~tsIn kw<"in"> expressionNoComma | |
|
expressionNoComma !rel ckw<"as"> (kw<"const"> | type) | |
|
expressionNoComma !equal CompareOp<"==" "="? | "!=" "="?> expressionNoComma | |
|
expressionNoComma !bitOr BitOp { "|" } expressionNoComma | |
|
expressionNoComma !bitXor BitOp<"^"> expressionNoComma | |
|
expressionNoComma !bitAnd BitOp { "&" } expressionNoComma | |
|
expressionNoComma !and LogicOp<"&&"> expressionNoComma | |
|
expressionNoComma !or LogicOp<"||" | "??"> expressionNoComma |
|
} |
|
|
|
AssignmentExpression { |
|
(VariableName | MemberExpression) !assign UpdateOp<($[+\-/%^] | "*" "*"? | "|" "|"? | "&" "&"? | "<<" | ">>" ">"? | "??") "="> |
|
expressionNoComma | |
|
(VariableName | MemberExpression | ArrayPattern | ObjectPattern) !assign "=" expressionNoComma |
|
} |
|
|
|
MemberExpression { |
|
expressionNoComma !member (("." | questionDot) (PropertyName | PrivatePropertyName) | questionDot? "[" expression "]") |
|
} |
|
|
|
ArgList { |
|
"(" commaSep<"..."? expressionNoComma> ")" |
|
} |
|
|
|
ArrowFunction { |
|
async? (ParamList { VariableDefinition } | ParamList TypeAnnotation?) "=>" (Block | expressionNoComma) |
|
} |
|
|
|
TypeArgList[@dynamicPrecedence=1] { |
|
@extend[@dialect=ts,@name="<"]<LessThan, "<"> commaSep<type> ">" |
|
} |
|
|
|
TypeParamList { |
|
"<" commaSep<typeParam> ">" |
|
} |
|
|
|
typeParam { TypeDefinition ~tsAngle (kw<"extends"> type)? ("=" type)? } |
|
|
|
typeofExpression { |
|
MemberExpression { typeofExpression !member (("." | questionDot) PropertyName | "[" expression "]") } | |
|
InstantiationExpression { typeofExpression !instantiate TypeArgList } | |
|
VariableName |
|
} |
|
|
|
type[@isGroup=Type] { |
|
ThisType { kw<"this"> } | |
|
LiteralType { |
|
ArithOp<"+" | "-">? Number | |
|
boolean | |
|
String |
|
} | |
|
TemplateType | |
|
NullType { kw<"null"> } | |
|
VoidType { kw<"void"> } | |
|
TypeofType { kw<"typeof"> typeofExpression } | |
|
KeyofType { !typePrefix tskw<"keyof"> type } | |
|
UniqueType { !typePrefix tskw<"unique"> type } | |
|
ImportType { kw<"import"> "(" String ")" } | |
|
InferredType { tskw<"infer"> TypeName } | |
|
ParenthesizedType { "(" type ")" } | |
|
FunctionSignature { TypeParamList? ParamTypeList "=>" type } | |
|
NewSignature { kw<"new"> ParamTypeList "=>" type } | |
|
IndexedType | |
|
TupleType { "[" commaSep<(Label ":")? type | "..." type> ~destructure "]" } | |
|
ArrayType { type "[" "]" | type "[" "]" } | |
|
ReadonlyType { tskw<"readonly"> !readonly type } | |
|
ObjectType | |
|
UnionType { |
|
type (!union unionOp type)+ | |
|
unionOp type (!unionPrefixed unionOp type)* |
|
} | |
|
IntersectionType { |
|
type (!intersection intersectionOp type)+ | |
|
intersectionOp type (!intersectionPrefixed intersectionOp type)* |
|
} | |
|
ConditionalType { type !typeExtends kw<"extends"> type questionOp ~arrow type LogicOp<":"> type } | |
|
ParameterizedType { (TypeName | IndexedType) !typeargs TypeArgList } | |
|
TypeName |
|
} |
|
|
|
IndexedType { |
|
type !typeMember ("." TypeName | "[" type "]")+ |
|
} |
|
|
|
ObjectType { |
|
"{" ( |
|
(MethodType | |
|
PropertyType | |
|
IndexSignature | |
|
CallSignature { ParamTypeList (TypeAnnotation | TypePredicate) } | |
|
NewSignature[@dynamicPrecedence=1] { @extend[@name=new]<word, "new"> ParamTypeList TypeAnnotation }) |
|
("," | semi) |
|
)* ~destructure "}" |
|
} |
|
|
|
IndexSignature { |
|
tsPkwMod<"readonly">? "[" PropertyDefinition { identifier } (TypeAnnotation | ~tsIn kw<"in"> type) "]" TypeAnnotation |
|
} |
|
|
|
MethodType { |
|
pkwMod<"async">? |
|
(pkwMod<"get"> | pkwMod<"set"> | Star)? |
|
PropertyDefinition |
|
functionSignature |
|
} |
|
|
|
PropertyType { |
|
(ArithOp<"+" | "-">? tsPkwMod<"readonly">)? |
|
PropertyDefinition |
|
(ArithOp<"+" | "-">? Optional)? |
|
TypeAnnotation |
|
} |
|
|
|
ParamTypeList[@name=ParamList] { |
|
"(" commaSep<"..."? pattern ~arrow Optional? ~arrow TypeAnnotation?> ")" |
|
} |
|
|
|
@skip {} { |
|
TemplateString[isolate] { |
|
templateStart (templateEscape | templateContent | templateExpr)* templateEnd |
|
} |
|
|
|
TemplateType[isolate] { |
|
templateStart (templateContent | templateType)* templateEnd |
|
} |
|
|
|
String[isolate] { |
|
'"' (stringContentDouble | Escape)* ('"' | "\n") | |
|
"'" (stringContentSingle | Escape)* ("'" | "\n") |
|
} |
|
|
|
BlockComment[isolate] { "/*" (blockCommentContent | blockCommentNewline)* blockCommentEnd } |
|
} |
|
|
|
templateExpr[@name=Interpolation,isolate] { InterpolationStart expression InterpolationEnd } |
|
|
|
templateType[@name=Interpolation,isolate] { InterpolationStart type InterpolationEnd } |
|
|
|
@skip {} { |
|
JSXElement { |
|
JSXSelfClosingTag | |
|
(JSXOpenTag | JSXFragmentTag) (JSXText | JSXElement | JSXEscape)* JSXCloseTag |
|
} |
|
} |
|
|
|
JSXSelfClosingTag { JSXStartTag jsxElementName jsxAttribute* JSXSelfCloseEndTag } |
|
|
|
JSXOpenTag { JSXStartTag jsxElementName jsxAttribute* JSXEndTag } |
|
|
|
JSXFragmentTag { JSXStartTag JSXEndTag } |
|
|
|
JSXCloseTag { JSXStartCloseTag jsxElementName? JSXEndTag } |
|
|
|
jsxElementName { |
|
JSXIdentifier | |
|
JSXBuiltin { JSXLowerIdentifier } | |
|
JSXNamespacedName | |
|
JSXMemberExpression |
|
} |
|
|
|
JSXMemberExpression { (JSXMemberExpression | JSXIdentifier | JSXLowerIdentifier) "." (JSXIdentifier | JSXLowerIdentifier) } |
|
|
|
JSXNamespacedName { (JSXIdentifier | JSXNamespacedName | JSXLowerIdentifier) ":" (JSXIdentifier | JSXLowerIdentifier) } |
|
|
|
jsxAttribute { |
|
JSXSpreadAttribute { "{" "..." expression "}" } | |
|
JSXAttribute { (JSXIdentifier | JSXNamespacedName | JSXLowerIdentifier) ("=" jsxAttributeValue)? } |
|
} |
|
|
|
jsxAttributeValue { |
|
JSXAttributeValue | |
|
JSXEscape { "{" expression "}" } | |
|
JSXElement |
|
} |
|
|
|
JSXEscape { "{" "..."? expression "}" } |
|
|
|
commaSep<content> { |
|
"" | content ("," content?)* |
|
} |
|
|
|
commaSep1<content> { |
|
content ("," content)* |
|
} |
|
|
|
// Keywords |
|
|
|
kw<term> { @specialize[@name={term}]<identifier, term> } |
|
|
|
// Contextual keywords |
|
|
|
ckw<term> { @extend[@name={term}]<identifier, term> } |
|
|
|
tskw<term> { @extend[@name={term},@dialect=ts]<identifier, term> } |
|
|
|
async { @extend[@name=async]<identifier, "async"> } |
|
|
|
// Contextual keyword in property context |
|
|
|
pkwMod<term> { @extend[@name={term}]<word, term> } |
|
|
|
tsPkwMod<term> { @extend[@name={term},@dialect=ts]<word, term> } |
|
|
|
semi { ";" | insertSemi } |
|
|
|
boolean { @specialize[@name=BooleanLiteral]<identifier, "true" | "false"> } |
|
|
|
Star { "*" } |
|
|
|
VariableName { identifier ~arrow } |
|
|
|
VariableDefinition { identifier ~arrow } |
|
|
|
TypeDefinition { identifier } |
|
|
|
TypeName { identifier ~arrow } |
|
|
|
Label { identifier } |
|
|
|
PropertyName { word ~propName } |
|
|
|
PropertyDefinition { word ~propName } |
|
|
|
PrivatePropertyName { privateIdentifier } |
|
|
|
PrivatePropertyDefinition { privateIdentifier } |
|
|
|
Optional { "?" } |
|
|
|
questionOp[@name=LogicOp] { "?" } |
|
|
|
unionOp[@name=LogicOp] { "|" } |
|
|
|
intersectionOp[@name=LogicOp] { "&" } |
|
|
|
@skip { spaces | newline | LineComment | BlockComment } |
|
|
|
@context trackNewline from "./tokens.js" |
|
|
|
@external tokens noSemicolon from "./tokens" { noSemi } |
|
|
|
@external tokens operatorToken from "./tokens" { |
|
incdec[@name=ArithOp], |
|
incdecPrefix[@name=ArithOp] |
|
questionDot[@name="?."] |
|
} |
|
|
|
@external tokens jsx from "./tokens" { JSXStartTag } |
|
|
|
@local tokens { |
|
InterpolationStart[closedBy=InterpolationEnd] { "${" } |
|
templateEnd { "`" } |
|
templateEscape[@name=Escape] { Escape } |
|
@else templateContent |
|
} |
|
|
|
@local tokens { |
|
blockCommentEnd { "*/" } |
|
blockCommentNewline { "\n" } |
|
@else blockCommentContent |
|
} |
|
|
|
@tokens { |
|
spaces[@export] { $[\u0009 \u000b\u00a0\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]+ } |
|
newline[@export] { $[\r\n\u2028\u2029] } |
|
|
|
LineComment[isolate] { "//" ![\n]* } |
|
|
|
Hashbang { "#!" ![\n]* } |
|
|
|
divide[@name=ArithOp] { "/" } |
|
|
|
@precedence { "/*", LineComment, divide } |
|
|
|
@precedence { "/*", LineComment, RegExp } |
|
|
|
identifierChar { @asciiLetter | $[_$\u{a1}-\u{10ffff}] } |
|
|
|
word { identifierChar (identifierChar | @digit)* } |
|
|
|
identifier { word } |
|
|
|
privateIdentifier { "#" word } |
|
|
|
@precedence { spaces, newline, identifier } |
|
|
|
@precedence { spaces, newline, JSXIdentifier, JSXLowerIdentifier } |
|
|
|
@precedence { spaces, newline, word } |
|
|
|
hex { @digit | $[a-fA-F] } |
|
|
|
Number { |
|
(@digit ("_" | @digit)* ("." ("_" | @digit)*)? | "." @digit ("_" | @digit)*) |
|
(("e" | "E") ("+" | "-")? ("_" | @digit)+)? | |
|
@digit ("_" | @digit)* "n" | |
|
"0x" (hex | "_")+ "n"? | |
|
"0b" $[01_]+ "n"? | |
|
"0o" $[0-7_]+ "n"? |
|
} |
|
|
|
@precedence { Number "." } |
|
|
|
Escape { |
|
"\\" ("x" hex hex | "u" ("{" hex+ "}" | hex hex hex hex) | ![xu]) |
|
} |
|
|
|
stringContentSingle { ![\\\n']+ } |
|
|
|
stringContentDouble { ![\\\n"]+ } |
|
|
|
templateStart { "`" } |
|
|
|
InterpolationEnd[openedBy=InterpolationStart] { "}" } |
|
|
|
ArithOp<expr> { expr } |
|
LogicOp<expr> { expr } |
|
BitOp<expr> { expr } |
|
CompareOp<expr> { expr } |
|
UpdateOp<expr> { expr } |
|
|
|
@precedence { "*", ArithOp } |
|
|
|
RegExp[isolate] { "/" (![/\\\n[] | "\\" ![\n] | "[" (![\n\\\]] | "\\" ![\n])* "]")+ ("/" $[dgimsuvy]*)? } |
|
|
|
LessThan[@name=CompareOp] { "<" } |
|
|
|
"="[@name=Equals] |
|
"..."[@name=Spread] |
|
"=>"[@name=Arrow] |
|
|
|
"(" ")" "[" "]" "{" "}" "<" ">" |
|
|
|
"." "," ";" ":" "@" |
|
|
|
JSXIdentifier { $[A-Z_$\u{a1}-\u{10ffff}] (identifierChar | @digit | "-")* } |
|
JSXLowerIdentifier[@name=JSXIdentifier] { $[a-z] (identifierChar | @digit | "-")* } |
|
|
|
JSXAttributeValue { '"' !["]* '"' | "'" ![']* "'" } |
|
|
|
JSXStartCloseTag { "</" } |
|
|
|
JSXEndTag { ">" } |
|
|
|
JSXSelfCloseEndTag { "/>" } |
|
|
|
JSXText { ![<{]+ } |
|
|
|
tsAngleOpen[@dialect=ts] { "<" } |
|
} |
|
|
|
@external tokens insertSemicolon from "./tokens" { insertSemi } |
|
|
|
@external propSource jsHighlight from "./highlight" |
|
|
|
@detectDelim |
|
|