Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
1 contributor

Users who have contributed to this file

363 lines (278 sloc) 9.7 KB
@precedence {
else @left,
member,
newArgs,
call,
taggedTemplate,
prefix,
postfix,
typeof,
exp @left,
times @left,
plus @left,
shift @left,
loop,
rel @left,
equal @left,
bitOr @left,
bitXor @left,
bitAnd @left,
and @left,
or @left,
ternary @left,
assign @left,
comma @left,
statement @cut
}
@top:script.document.lang=javascript { statement+ }
statement {
exportDeclaration |
importDeclaration |
(kw<"for"> ckw<"await">? (forSpec | forInSpec | forOfSpec) statement):for.loop.scope.statement |
(kw<"while"> parenthesizedExpression statement):while.loop.statement |
(kw<"with"> parenthesizedExpression statement):with.statement |
(kw<"do"> statement kw<"while"> parenthesizedExpression semi):do.loop.statement |
(kw<"if"> parenthesizedExpression statement (!else kw<"else"> statement)?):if.conditional.statement |
(kw<"switch"> parenthesizedExpression ("{" switchItem* "}"):block.statement):switch.statement |
(kw<"try"> block (kw<"catch"> ("(" pattern ")")? block)? (kw<"finally"> block)?):try.statement |
(kw<"return"> (noSemi expression)? semi):return.statement |
(kw<"throw"> expression semi):throw.statement |
(kw<"break"> (noSemi label)? semi):break.statement |
(kw<"continue"> (noSemi label)? semi):continue.statement |
(kw<"debugger"> semi):debugger.statement |
block |
labeledStatement |
declaration |
(expression semi):expression.statement |
";"
}
exportDeclaration:export.declaration.statement {
kw<"export"> star ckw<"from"> string semi |
kw<"export"> kw<"default"> (functionDeclaration | classDeclaration | expression semi) |
kw<"export"> declaration |
kw<"export"> exportGroup (ckw<"from"> string)? semi
}
exportGroup:export.group {
"{" commaSep<variable (ckw<"as"> word:variable.name)?> "}"
}
importDeclaration:import.declaration.statement {
kw<"import"> (star ckw<"as"> word:definition.variable.name | commaSep<definition | importGroup>) ckw<"from"> string semi |
kw<"import"> string semi
}
importGroup:import.group {
"{" commaSep<definition | variable ckw<"as"> word:definition.variable.name> "}"
}
labeledStatement:labeled.statement {
label ":" statement
}
forSpec:for.spec {
"("
(variableDeclaration | expression ";" | ";") expression? ";" expression?
")"
}
forXSpec<op> {
"("
((kw<"let"> | kw<"var"> | kw<"const">) pattern | variable | memberExpression | arrayPattern | objectPattern)
!loop op expression
")"
}
forInSpec:in.for.spec { forXSpec<kwOp<"in">> }
forOfSpec:of.for.spec { forXSpec<kw<"of">> }
declaration {
functionDeclaration | classDeclaration | variableDeclaration
}
functionDeclaration:function.declaration.statement {
ckw<"async">? !statement kw<"function"> star? definition? paramList block
}
classDeclaration:class.declaration.statement {
!statement kw<"class"> definition (kw<"extends"> expression)? classBody
}
classBody:class.body {
"{" (methodDeclaration | ";")* "}"
}
methodDeclaration:method.property.declaration {
pkw<"static">?
pkw<"async">?
(pkw<"get"> | pkw<"set"> | star)?
propertyNameDef
paramList
block
}
variableDeclaration:variable.declaration.statement {
(kw<"let"> | kw<"var"> | kw<"const">) commaSep1<patternAssign> semi
}
pattern { definition | arrayPattern | objectPattern }
arrayPattern:array.pattern { "[" commaSep<"..." patternAssign | patternAssign> ~destructure "]" }
objectPattern:object.pattern { "{" commaSep<patternProperty> ~destructure "}" }
patternAssign {
pattern (op<"="> expressionNoComma)?
}
paramList:parameter.list {
"(" commaSep<"..." patternAssign | patternAssign> ")"
}
block:block.statement {
!statement "{" statement* "}"
}
switchItem {
(kw<"case"> expression ":"):case.label |
(kw<"default"> ":"):default.label |
statement
}
expression {
expressionNoComma | sequenceExpression
}
sequenceExpression:sequence.expression {
expressionNoComma !comma ("," expressionNoComma)+
}
expressionNoComma {
number |
string |
templateString |
variable |
boolean |
this |
null |
super |
regExp |
arrayExpression |
("{" commaSep<property> ~destructure "}"):object.expression |
newExpression |
unaryExpression |
parenthesizedExpression |
classExpression |
functionExpression |
arrowFunction |
memberExpression |
binaryExpression |
(expressionNoComma !ternary op<"?"> expressionNoComma ":":operator.name expressionNoComma):conditional.operator.expression |
assignmentExpression |
(expressionNoComma !postfix postfixOp):unary.postfix.operator.expression |
(expressionNoComma !call argList):call.expression |
(expressionNoComma !taggedTemplate templateString):tagged.template.expression
}
parenthesizedExpression:parenthesized.expression { "(" expression ")" }
arrayExpression:array.expression {
"[" commaSep1<expressionNoComma | ""> ~destructure "]"
}
propName { propertyNameDef | "[" expression "]" | number | string }
property:property.declaration {
pkw<"async">? (pkw<"get"> | pkw<"set"> | star)? propName paramList block |
propName ~destructure (":" expressionNoComma)? |
"..." expressionNoComma
}
patternProperty:property.declaration {
"..." patternAssign |
(propertyName | number | string) ~destructure (":" pattern)? (op<"="> expressionNoComma)?
}
classExpression:class.expression {
kw<"class"> definition? (kw<"extends"> expression)? classBody
}
functionExpression:function.expression {
kw<"function"> star? definition? paramList block
}
newExpression:new.expression {
kw<"new"> expressionNoComma (!newArgs argList)?
}
unaryExpression:unary.prefix.operator.expression {
!prefix (ckw<"await"> | ckw<"yield"> | kwOp<"void"> | kwOp<"typeof"> | kwOp<"delete"> | op<"!"> | op<"~"> | op<"++" | "--"> | op<"+" | "-">)
expressionNoComma
}
binaryExpression:binary.operator.expression {
expressionNoComma !exp op<"**"> expressionNoComma |
expressionNoComma !times (divide | op<"%"> | "*":operator.name) expressionNoComma |
expressionNoComma !plus op<"+" | "-"> expressionNoComma |
expressionNoComma !shift op<">>" ">"? | "<<"> expressionNoComma |
expressionNoComma !rel (op<"<" "="? | ">" "="?> | kwOp<"in"> | kwOp<"instanceof">) expressionNoComma |
expressionNoComma !equal op<"==" "="? | "!=" "="?> expressionNoComma |
expressionNoComma !bitOr op<"|"> expressionNoComma |
expressionNoComma !bitXor op<"^"> expressionNoComma |
expressionNoComma !bitAnd op<"&"> expressionNoComma |
expressionNoComma !and op<"&&"> expressionNoComma |
expressionNoComma !or op<"||"> expressionNoComma
}
assignmentExpression:assignment.expression {
(variable | memberExpression) !assign op<([+\-/|&%^] | "*" "*"? | "<<" | ">>" ">"?) "="> expressionNoComma |
(variable | memberExpression | arrayPattern | objectPattern) !assign op<"="> expressionNoComma
}
memberExpression:member.expression {
expressionNoComma !member ("." propertyName | "[" expression "]")
}
argList:argument.list {
"(" commaSep<"..."? expressionNoComma> ")"
}
arrowFunction:arrow.function.expression {
ckw<"async">? (definition:parameter.list | paramList) "=>" (block | expression)
}
@skip {} {
templateString:template.string.literal.expression {
templateStart (templateContent | templateExpr)* templateEnd
}
}
templateExpr { templateDollarBrace expression templateClosingBrace }
commaSep<content> {
"" | content ("," content?)*
}
commaSep1<content> {
content ("," content)*
}
kw<term> { @specialize<identifier, term, :$term.keyword> }
kwOp<term> { @specialize<identifier, term, :$term.operator.keyword> }
// Contextual keywords
ckw<term> { @extend<identifier, term, :$term.keyword> }
// Contextual keyword in property context
pkw<term> { @extend<word, term, :$term.keyword> }
semi { ";" | insertSemi }
boolean { @specialize<identifier, "true" | "false", :boolean.literal.expression> }
this { @specialize<identifier, "this", :this.keyword.expression> }
null { @specialize<identifier, "null", :null.keyword.expression> }
super { @specialize<identifier, "super", :super.keyword.expression> }
star:star.punctuation { "*" }
variable:variable.name { identifier ~arrow }
definition:definition.variable.name.def=variable { identifier ~arrow }
label:label.name { identifier }
propertyName:property.name { word }
propertyNameDef:definition.property.name { word }
@skip { whitespace | lineComment | blockComment }
@external-tokens noSemicolon from "./tokens" { noSemi }
@external-tokens postfix from "./tokens" { postfixOp:operator.name }
@tokens {
whitespace { std.whitespace+ }
lineComment:line.comment { "//" [^\n]* }
blockComment:block.comment { "/*" blockCommentRest }
blockCommentRest { [^*] blockCommentRest | "*" blockCommentAfterStar }
blockCommentAfterStar { "/" | "*" blockCommentAfterStar | [^/*] blockCommentRest }
divide:operator.name { "/" }
@precedence { blockComment, lineComment, divide }
@precedence { blockComment, lineComment, regExp }
identifierChar { std.asciiLetter | [_$\u{a1}-\u{10ffff}] }
word { identifierChar (identifierChar | std.digit)* }
identifier { word }
@precedence { identifier, whitespace }
@precedence { word, whitespace }
number:number.literal.expression {
(std.digit+ ("." std.digit*)? | "." std.digit+) (("e" | "E") ("+" | "-")? std.digit+)? |
"0x" (std.digit | [a-fA-F])+ |
"0b" [01]+ |
"0o" [0-7]+
}
string:string.literal.expression {
'"' ([^\\\n"] | "\\" _)* '"'? |
"'" ([^\\\n'] | "\\" _)* "'"?
}
templateStart { "`" }
templateClosingBrace { "}" }
op<expr>:operator.name { expr }
regExp:regexp.literal.expression { "/" ([^/\\\n[] | "\\" [^\n] | "[" ([^\n\\\]] | "\\" [^\n])* "]")+ ("/" [gimsuy]*)? }
}
@tags {
@detect-delim
@punctuation<"()[]{},:.;">
"...":spread.punctuation
"=>":arrow.punctuation
}
@external-tokens insertSemicolon from "./tokens" { insertSemi }
@external-tokens template from "./tokens" {
templateContent,
templateDollarBrace,
templateEnd
}
You can’t perform that action at this time.