module lang::javascript::saner::Syntax
rascal-0.40.16
A saner grammar for JavaScript It assumes: - semicolons are present - there is no comma expression.
Usage
import lang::javascript::saner::Syntax;
syntax Source
start syntax Source
= source: Statement* statements
;
syntax Statement
syntax Statement
= varDecl: VarDecl varDecl
| empty: ";"
| block: "{" Statement* statements "}"
| expression: Expression!function expression ";"
// Block level things
| function: Function function
| ifThen: "if" "(" Expression cond ")" Statement body () !>> "else"
| ifThenElse: "if" "(" Expression cond ")" Statement body "else" Statement elseBody
| doWhile: "do" Statement body "while" "(" Expression cond ")" ";"
| whileDo: "while" "(" Expression cond ")" Statement body
| forDo: "for" "(" {Expression ","}* inits ";" {Expression ","}* conds ";" {Expression ","}* ops ")" Statement body
| forDoDeclarations: "for" "(" "var" {VariableDeclarationNoIn ","}+ decls ";" {Expression ","}* conds ";" {Expression ","}* ops ")" Statement body
| forIn: "for" "(" Expression var "in" Expression obj ")" Statement body
| forInDeclaration: "for" "(" "var" Id varId "in" Expression obj ")" Statement body
| with: "with" "(" Expression scope ")" Statement body
// Non local control flow
| returnExp: "return" Expression result ";"
| returnNoExp: "return" ";"
| throwExp: "throw" Expression result ";"
| throwNoExp: "throw" ";"
| continueLabel: "continue" Id label ";"
| continueNoLabel: "continue" ";"
| breakLabel: "break" Id label ";"
| breakNoLabel: "break" ";"
| debugger: "debugger" ";"
| labeled: Id label ":" Statement statement
| switchCase: "switch" "(" Expression cond ")" "{" CaseClause* clauses "}"
| tryCatch: "try" Statement body "catch" "(" Id varId ")" Statement catchBody
| tryFinally: "try" Statement body "finally" Statement finallyBody
| tryCatchFinally: "try" Statement body "catch" "(" Id varId ")" Statement catchBody "finally" Statement finallyBody
;
syntax VariableDeclaration
syntax VariableDeclaration
= init: Id id "=" Expression init
| nonInit: Id id
;
syntax VariableDeclarationNoIn
syntax VariableDeclarationNoIn
= init: Id id "=" Expression!inn init
| nonInit: Id id
;
syntax CaseClause
syntax CaseClause
= caseOf: "case" Expression guard ":" Statement* body
| defaultCase: "default" ":" Statement* body
;
syntax Function
syntax Function
= "function" Id name "(" {Id ","}* parameters ")" "{" Statement* statements "}"
| "function" "(" {Id ","}* parameters ")" "{" Statement* statements "}"
;
syntax Expression
syntax Expression
= array: "[" {Expression ","}* elements ","? "]"
| objectDefinition:"{" {PropertyAssignment ","}* properties ","? "}"
| this: "this"
| var: Id name
| literal: Literal literal
| bracket \bracket: "(" Expression arg ")"
| function: Function function
> property: Expression obj "." Id fieldId
| call: Expression func "(" { Expression ","}* params ")"
| member: Expression obj "[" Expression field "]"
> new: "new" Expression cons
> postIncr: Expression arg "++"
| postDec: Expression arg "--"
> delete: "delete" Expression arg
| typeof: "typeof" Expression arg
| preIncr: "++" Expression arg
| preDecr: "--" Expression arg
| prefixPlus: "+" !>> [+=] Expression arg
| prefixMin: "-" !>> [\-=] Expression arg
| binNeg: "~" Expression arg
| not: "!" !>> [=] Expression arg
>
left (
mul: Expression lhs "*" !>> [*=] Expression rhs
| div: Expression lhs "/" !>> [/=] Expression rhs
| rem: Expression lhs "%" !>> [%=] Expression rhs
)
>
left (
add: Expression lhs "+" !>> [+=] Expression rhs
| sub: Expression lhs "-" !>> [\-=] Expression rhs
)
> // right???
left (
shl: Expression lhs "\<\<" Expression rhs
| shr: Expression lhs "\>\>" !>> [\>] Expression rhs
| shrr: Expression lhs "\>\>\>" Expression rhs
)
>
non-assoc (
lt: Expression lhs "\<" Expression rhs
| leq: Expression lhs "\<=" Expression rhs
| gt: Expression lhs "\>" Expression rhs
| geq: Expression lhs "\>=" Expression rhs
| instanceof: Expression lhs "instanceof" Expression rhs
| inn: Expression lhs "in" Expression rhs
)
>
right (
eqq: Expression lhs "===" Expression rhs
| neqq: Expression lhs "!==" Expression rhs
| eq: Expression lhs "==" !>> [=] Expression rhs
| neq: Expression lhs "!=" !>> [=] Expression rhs
)
> right binAnd: Expression lhs "&" !>> [&=] Expression rhs
> right binXor: Expression lhs "^" !>> [=] Expression rhs
> right binOr: Expression lhs "|" !>> [|=] Expression rhs
> left and: Expression lhs "&&" Expression rhs
> left or: Expression lhs "||" Expression rhs
> cond: Expression!cond cond "?" Expression!cond then ":" Expression elseExp
> right (
assign: Expression lhs "=" !>> [=] Expression rhs
| assignMul: Expression lhs "*=" Expression rhs
| assignDiv: Expression lhs "/=" Expression rhs
| assignRem: Expression lhs "%=" Expression rhs
| assignAdd: Expression lhs "+=" Expression rhs
| assignSub: Expression lhs "-=" Expression rhs
| assignShl: Expression lhs "\<\<=" Expression rhs
| assignShr: Expression lhs "\>\>=" Expression rhs
| assignShrr: Expression lhs "\>\>\>=" Expression rhs
| assignBinAnd: Expression lhs "&=" Expression rhs
| assignBinXor: Expression lhs "^=" Expression rhs
| assignBinOr: Expression lhs "|=" Expression rhs
)
;
syntax VarDecl
syntax VarDecl
= "var" {VariableDeclaration ","}+ declarations ";"
;
syntax PropertyName
syntax PropertyName
= id: Id name
| string: String key
| numeric: Numeric numeric
;
syntax PropertyAssignment
syntax PropertyAssignment
= property: PropertyName name ":" Expression value
| get: "get" PropertyName name "(" ")" "{" Statement* body "}"
| \set: "set" PropertyName name "(" Id x ")" "{" Statement* body "}"
;
syntax Literal
syntax Literal
= null: "null"
| boolean: Boolean bool
| numeric: Numeric num
| string: String str
| regexp: RegularExpression regexp
;
syntax Boolean
syntax Boolean
= t: "true"
| f: "false"
;
syntax Numeric
syntax Numeric
= decimal: [a-zA-Z$_0-9] !<< Decimal decimal
| hexadecimal: [a-zA-Z$_0-9] !<< HexInteger hexInt
;
syntax Decimal
lexical Decimal
= DecimalInteger [.] [0-9]* ExponentPart?
| [.] [0-9]+ ExponentPart?
| DecimalInteger ExponentPart?
;
syntax DecimalInteger
lexical DecimalInteger
= [0]
| [1-9][0-9]*
!>> [0-9]
;
syntax ExponentPart
lexical ExponentPart
= [eE] SignedInteger
;
syntax SignedInteger
lexical SignedInteger
= [+\-]? [0-9]+ !>> [0-9]
;
syntax HexInteger
lexical HexInteger
= [0] [Xx] [0-9a-fA-F]+ !>> [a-zA-Z_]
;
syntax String
lexical String
= [\"] DoubleStringChar* [\"]
| [\'] SingleStringChar* [\']
;
syntax DoubleStringChar
lexical DoubleStringChar
= ![\"\\\n]
| [\\] EscapeSequence
;
syntax SingleStringChar
lexical SingleStringChar
= ![\'\\\n]
| [\\] EscapeSequence
;
syntax EscapeSequence
lexical EscapeSequence
= CharacterEscapeSequence
| [0] !>> [0-9]
| HexEscapeSequence
| UnicodeEscapeSequence
;
syntax CharacterEscapeSequence
lexical CharacterEscapeSequence
= SingleEscapeCharacter
| NonEscapeCharacter
;
syntax SingleEscapeCharacter
lexical SingleEscapeCharacter
= [\'\"\\bfnrtv]
;
syntax NonEscapeCharacter
lexical NonEscapeCharacter
// SourceCharacter but not one of EscapeCharacter or LineTerminator
= ![\n\'\"\\bfnrtv0-9xu]
;
syntax EscapeCharacter
lexical EscapeCharacter
= SingleEscapeCharacter
| [0-9]
| [xu]
;
syntax HexDigit
lexical HexDigit
= [a-fA-F0-9]
;
syntax HexEscapeSequence
lexical HexEscapeSequence
= [x] HexDigit HexDigit
;
syntax UnicodeEscapeSequence
lexical UnicodeEscapeSequence
= "u" HexDigit HexDigit HexDigit HexDigit
;
syntax RegularExpression
lexical RegularExpression
= [/] RegularExpressionBody [/] RegularExpressionFlags
;
syntax RegularExpressionBody
lexical RegularExpressionBody
= RegularExpressionFirstChar RegularExpressionChar*
;
syntax RegularExpressionFirstChar
lexical RegularExpressionFirstChar
= ![*/\[\n\\]
| RegularExpressionBackslashSequence
| RegularExpressionClass
;
syntax RegularExpressionChar
lexical RegularExpressionChar
= ![/\[\n\\]
| RegularExpressionBackslashSequence
| RegularExpressionClass
;
syntax RegularExpressionBackslashSequence
lexical RegularExpressionBackslashSequence
= [\\] ![\n]
;
syntax RegularExpressionClass
lexical RegularExpressionClass
= [\[] RegularExpressionClassChar* [\]]
;
syntax RegularExpressionClassChar
lexical RegularExpressionClassChar
= ![\n\]\\]
| RegularExpressionBackslashSequence
;
syntax RegularExpressionFlags
lexical RegularExpressionFlags
= [a-zA-Z]* !>> [a-zA-Z]
;
syntax Whitespace
lexical Whitespace
= [\t-\n\r\ ]
;
syntax Comment
lexical Comment
= @category="Comment" "/*" CommentChar* "*/"
| @category="Comment" "//" ![\n]* $
;
syntax CommentChar
lexical CommentChar
= ![*]
| [*] !>> [/]
;
syntax LAYOUT
lexical LAYOUT
= Whitespace
| Comment
;
syntax LAYOUTLIST
layout LAYOUTLIST
= LAYOUT*
!>> [\t\ \n]
!>> "/*"
!>> "//" ;
syntax Id
lexical Id
= ([a-zA-Z$_0-9] !<< [$_a-zA-Z] [a-zA-Z$_0-9]* !>> [a-zA-Z$_0-9]) \ Reserved
;
syntax Reserved
keyword Reserved =
"break" |
"case" |
"catch" |
"continue" |
"debugger" |
"default" |
"delete" |
"do" |
"else" |
"finally" |
"for" |
"function" |
"if" |
"instanceof" |
"in" |
"new" |
"return" |
"switch" |
"this" |
"throw" |
"try" |
"typeof" |
"var" |
"void" |
"while" |
"with" |
"abstract" |
"boolean" |
"byte" |
"char" |
"class" |
"const" |
"double" |
"enum" |
"export" |
"extends" |
"final" |
"float" |
"goto" |
"implements" |
"import" |
"interface" |
"int" |
"long" |
"native" |
"package" |
"private" |
"protected" |
"public" |
"short" |
"static" |
"super" |
"synchronized" |
"throws" |
"transient" |
"volatile" |
"null" |
"true" |
"false"
;