Comments
Syntax
LineComment  / / LineCommentCharacters
LineCommentCharacters 
	«empty»
|	LineCommentCharacters NonTerminator
UnicodeCharacter  Any Unicode character
NonTerminator  UnicodeCharacter except LineTerminator
SingleLineBlockComment  / * BlockCommentCharacters * /
BlockCommentCharacters 
	«empty»
|	BlockCommentCharacters NonTerminatorOrSlash
|	PreSlashCharacters /
PreSlashCharacters 
	«empty»
|	BlockCommentCharacters NonTerminatorOrAsteriskOrSlash
|	PreSlashCharacters /
NonTerminatorOrSlash  NonTerminator except /
NonTerminatorOrAsteriskOrSlash  NonTerminator except * | /
MultiLineBlockComment  / * MultiLineBlockCommentCharacters BlockCommentCharacters * /
MultiLineBlockCommentCharacters 
	BlockCommentCharacters LineTerminator
|	MultiLineBlockCommentCharacters BlockCommentCharacters LineTerminator
White space
Syntax
WhiteSpace 
	«empty»
|	WhiteSpace WhiteSpaceCharacter
|	WhiteSpace SingleLineBlockComment
WhiteSpaceCharacter  «TAB» | «VT» | «FF» | «SP»
Line breaks
Syntax
LineBreak 
	LineTerminator
|	LineComment LineTerminator
|	MultiLineBlockComment
LineTerminator  «LF» | «CR»
LineBreaks 
	LineBreak
|	LineBreaks WhiteSpace LineBreak
Tokens
Syntax
NextToken  WhiteSpace Token
Token 
	LineBreaks
|	IdentifierOrReservedWord
|	Punctuator
|	NumericLiteral
|	StringLiteral
|	EndOfInput
EndOfInput 
	End
|	LineComment End
Semantics
type Token
  = oneof {
           identifier: String;
           reservedWord: String;
           punctuator: String;
           number: Double;
           string: String;
           lineBreaks;
           end}
action Token[NextToken] : Token
Token[NextToken  WhiteSpace Token] = Token[Token]
action Token[Token] : Token
Token[Token  LineBreaks] = lineBreaks
Token[Token  IdentifierOrReservedWord] = Token[IdentifierOrReservedWord]
Token[Token  Punctuator] = punctuator Punctuator[Punctuator]
Token[Token  NumericLiteral] = number DoubleValue[NumericLiteral]
Token[Token  StringLiteral] = string StringValue[StringLiteral]
Token[Token  EndOfInput] = end
Keywords
Syntax
IdentifierName 
	IdentifierLetter
|	IdentifierName IdentifierLetter
|	IdentifierName DecimalDigit
IdentifierLetter 
	A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
|	a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z
|	$ | _
DecimalDigit  0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Semantics
action Name[IdentifierName] : String
Name[IdentifierName  IdentifierLetter] = [CharacterValue[IdentifierLetter]]
Name[IdentifierName  IdentifierName1 IdentifierLetter]
  = Name[IdentifierName1]  [CharacterValue[IdentifierLetter]]
Name[IdentifierName  IdentifierName1 DecimalDigit]
  = Name[IdentifierName1]  [CharacterValue[DecimalDigit]]
action CharacterValue[IdentifierLetter] : Character = IdentifierLetter
action CharacterValue[DecimalDigit] : Character = DecimalDigit
action DigitValue[DecimalDigit] : Integer = digitValue(DecimalDigit)
keywords : String[]
  = [“break”,
      “case”,
      “catch”,
      “continue”,
      “default”,
      “delete”,
      “do”,
      “else”,
      “finally”,
      “for”,
      “function”,
      “if”,
      “in”,
      “new”,
      “return”,
      “switch”,
      “this”,
      “throw”,
      “try”,
      “typeof”,
      “var”,
      “void”,
      “while”,
      “with”]
futureReservedWords : String[]
  = [“class”, “const”, “debugger”, “enum”, “export”, “extends”, “import”, “super”]
literals : String[] = [“null”, “true”, “false”]
reservedWords : String[] = keywords  futureReservedWords  literals
member(id: String, list: String[]) : Boolean
  = if empty(list)
     then false
     else let s: String = first(list)
           in if id = s
               then true
               else member(id, rest(list))
Syntax
IdentifierOrReservedWord  IdentifierName
Semantics
action Token[IdentifierOrReservedWord] : Token
Token[IdentifierOrReservedWord  IdentifierName]
  = let id: String = Name[IdentifierName]
     in if member(id, reservedWords)
         then reservedWord id
         else identifier id
Punctuators
Syntax
Punctuator 
	=
|	>
|	<
|	= =
|	= = =
|	< =
|	> =
|	! =
|	! = =
|	,
|	!
|	~
|	?
|	:
|	.
|	& &
|	| |
|	+ +
|	- -
|	+
|	-
|	*
|	/
|	&
|	|
|	^
|	%
|	< <
|	> >
|	> > >
|	+ =
|	- =
|	* =
|	/ =
|	& =
|	| =
|	^ =
|	% =
|	< < =
|	> > =
|	> > > =
|	(
|	)
|	{
|	}
|	[
|	]
|	;
Semantics
action Punctuator[Punctuator] : String
Punctuator[Punctuator  =] = “=”
Punctuator[Punctuator  >] = “>”
Punctuator[Punctuator  <] = “<”
Punctuator[Punctuator  = =] = “==”
Punctuator[Punctuator  = = =] = “===”
Punctuator[Punctuator  < =] = “<=”
Punctuator[Punctuator  > =] = “>=”
Punctuator[Punctuator  ! =] = “!=”
Punctuator[Punctuator  ! = =] = “!==”
Punctuator[Punctuator  ,] = “,”
Punctuator[Punctuator  !] = “!”
Punctuator[Punctuator  ~] = “~”
Punctuator[Punctuator  ?] = “?”
Punctuator[Punctuator  :] = “:”
Punctuator[Punctuator  .] = “.”
Punctuator[Punctuator  & &] = “&&”
Punctuator[Punctuator  | |] = “||”
Punctuator[Punctuator  + +] = “++”
Punctuator[Punctuator  - -] = “--”
Punctuator[Punctuator  +] = “+”
Punctuator[Punctuator  -] = “-”
Punctuator[Punctuator  *] = “*”
Punctuator[Punctuator  /] = “/”
Punctuator[Punctuator  &] = “&”
Punctuator[Punctuator  |] = “|”
Punctuator[Punctuator  ^] = “^”
Punctuator[Punctuator  %] = “%”
Punctuator[Punctuator  < <] = “<<”
Punctuator[Punctuator  > >] = “>>”
Punctuator[Punctuator  > > >] = “>>>”
Punctuator[Punctuator  + =] = “+=”
Punctuator[Punctuator  - =] = “-=”
Punctuator[Punctuator  * =] = “*=”
Punctuator[Punctuator  / =] = “/=”
Punctuator[Punctuator  & =] = “&=”
Punctuator[Punctuator  | =] = “|=”
Punctuator[Punctuator  ^ =] = “^=”
Punctuator[Punctuator  % =] = “%=”
Punctuator[Punctuator  < < =] = “<<=”
Punctuator[Punctuator  > > =] = “>>=”
Punctuator[Punctuator  > > > =] = “>>>=”
Punctuator[Punctuator  (] = “(”
Punctuator[Punctuator  )] = “)”
Punctuator[Punctuator  {] = “{”
Punctuator[Punctuator  }] = “}”
Punctuator[Punctuator  [] = “[”
Punctuator[Punctuator  ]] = “]”
Punctuator[Punctuator  ;] = “;”
Numeric literals
Syntax
NumericLiteral 
	DecimalLiteral
|	HexIntegerLiteral
|	OctalIntegerLiteral
Semantics
action DoubleValue[NumericLiteral] : Double
DoubleValue[NumericLiteral  DecimalLiteral]
  = rationalToDouble(RationalValue[DecimalLiteral])
DoubleValue[NumericLiteral  HexIntegerLiteral]
  = rationalToDouble(IntegerValue[HexIntegerLiteral])
DoubleValue[NumericLiteral  OctalIntegerLiteral]
  = rationalToDouble(IntegerValue[OctalIntegerLiteral])
expt(base: Rational, exponent: Integer) : Rational
  = if exponent = 0
     then 1
     else if exponent < 0
     then 1/expt(base, –exponent)
     else base*expt(base, exponent – 1)
Syntax
DecimalLiteral  Mantissa Exponent
Mantissa 
	DecimalIntegerLiteral
|	DecimalIntegerLiteral .
|	DecimalIntegerLiteral . Fraction
|	. Fraction
DecimalIntegerLiteral 
	0
|	NonZeroDecimalDigits
NonZeroDecimalDigits 
	NonZeroDigit
|	NonZeroDecimalDigits DecimalDigit
NonZeroDigit  1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Fraction  DecimalDigits
Semantics
action RationalValue[DecimalLiteral] : Rational
RationalValue[DecimalLiteral  Mantissa Exponent]
  = RationalValue[Mantissa]*expt(10, IntegerValue[Exponent])
action RationalValue[Mantissa] : Rational
RationalValue[Mantissa  DecimalIntegerLiteral] = IntegerValue[DecimalIntegerLiteral]
RationalValue[Mantissa  DecimalIntegerLiteral .] = IntegerValue[DecimalIntegerLiteral]
RationalValue[Mantissa  DecimalIntegerLiteral . Fraction]
  = IntegerValue[DecimalIntegerLiteral] + RationalValue[Fraction]
RationalValue[Mantissa  . Fraction] = RationalValue[Fraction]
action IntegerValue[DecimalIntegerLiteral] : Integer
IntegerValue[DecimalIntegerLiteral  0] = 0
IntegerValue[DecimalIntegerLiteral  NonZeroDecimalDigits]
  = IntegerValue[NonZeroDecimalDigits]
action IntegerValue[NonZeroDecimalDigits] : Integer
IntegerValue[NonZeroDecimalDigits  NonZeroDigit] = DecimalValue[NonZeroDigit]
IntegerValue[NonZeroDecimalDigits  NonZeroDecimalDigits1 DecimalDigit]
  = 10*IntegerValue[NonZeroDecimalDigits1] + DecimalValue[DecimalDigit]
action DigitValue[NonZeroDigit] : Integer = digitValue(NonZeroDigit)
action RationalValue[Fraction] : Rational
RationalValue[Fraction  DecimalDigits]
  = IntegerValue[DecimalDigits]/expt(10, NDigits[DecimalDigits])
Syntax
Exponent 
	«empty»
|	ExponentIndicator SignedInteger
ExponentIndicator  E | e
SignedInteger 
	DecimalDigits
|	+ DecimalDigits
|	- DecimalDigits
Semantics
action IntegerValue[Exponent] : Integer
IntegerValue[Exponent  «empty»] = 0
IntegerValue[Exponent  ExponentIndicator SignedInteger] = IntegerValue[SignedInteger]
action IntegerValue[SignedInteger] : Integer
IntegerValue[SignedInteger  DecimalDigits] = IntegerValue[DecimalDigits]
IntegerValue[SignedInteger  + DecimalDigits] = IntegerValue[DecimalDigits]
IntegerValue[SignedInteger  - DecimalDigits] = –IntegerValue[DecimalDigits]
Syntax
DecimalDigits 
	DecimalDigit
|	DecimalDigits DecimalDigit
Semantics
action IntegerValue[DecimalDigits] : Integer
action NDigits[DecimalDigits] : Integer
IntegerValue[DecimalDigits  DecimalDigit] = DecimalValue[DecimalDigit]
NDigits[DecimalDigits  DecimalDigit] = 1
IntegerValue[DecimalDigits  DecimalDigits1 DecimalDigit]
  = 10*IntegerValue[DecimalDigits1] + DecimalValue[DecimalDigit]
NDigits[DecimalDigits  DecimalDigits1 DecimalDigit] = NDigits[DecimalDigits1] + 1
Syntax
HexIntegerLiteral 
	0 HexIndicator HexDigit
|	HexIntegerLiteral HexDigit
HexIndicator  X | x
HexDigit  0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | a | b | c | d | e | f
OctalIntegerLiteral 
	0 OctalDigit
|	OctalIntegerLiteral OctalDigit
OctalDigit  0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
Semantics
action IntegerValue[HexIntegerLiteral] : Integer
IntegerValue[HexIntegerLiteral  0 HexIndicator HexDigit] = HexValue[HexDigit]
IntegerValue[HexIntegerLiteral  HexIntegerLiteral1 HexDigit]
  = 16*IntegerValue[HexIntegerLiteral1] + HexValue[HexDigit]
action DigitValue[HexDigit] : Integer = digitValue(HexDigit)
action IntegerValue[OctalIntegerLiteral] : Integer
IntegerValue[OctalIntegerLiteral  0 OctalDigit] = OctalValue[OctalDigit]
IntegerValue[OctalIntegerLiteral  OctalIntegerLiteral1 OctalDigit]
  = 8*IntegerValue[OctalIntegerLiteral1] + OctalValue[OctalDigit]
action CharacterValue[OctalDigit] : Character = OctalDigit
action DigitValue[OctalDigit] : Integer = digitValue(OctalDigit)
String literals
Syntax
Quote  {single, double}
StringLiteral 
	' StringCharssingle '
|	" StringCharsdouble "
Semantics
action StringValue[StringLiteral] : String
StringValue[StringLiteral  ' StringCharssingle '] = StringValue[StringCharssingle]
StringValue[StringLiteral  " StringCharsdouble "] = StringValue[StringCharsdouble]
Syntax
StringCharsQuote 
	OrdinaryStringCharsQuote
|	StringCharsQuote \ ShortOctalEscape
OrdinaryStringCharsQuote 
	«empty»
|	StringCharsQuote PlainStringChar
|	StringCharsQuote PlainStringQuoteQuote
|	OrdinaryStringCharsQuote OctalDigit
|	StringCharsQuote \ OrdinaryEscape
PlainStringChar  UnicodeCharacter except ' | " | \ | OctalDigit | LineTerminator
PlainStringQuotesingle  "
PlainStringQuotedouble  '
Semantics
action StringValue[StringCharsQuote] : String
StringValue[StringCharsQuote  OrdinaryStringCharsQuote]
  = StringValue[OrdinaryStringCharsQuote]
StringValue[StringCharsQuote  StringCharsQuote1 \ ShortOctalEscape]
  = StringValue[StringCharsQuote1]  [CharacterValue[ShortOctalEscape]]
action StringValue[OrdinaryStringCharsQuote] : String
StringValue[OrdinaryStringCharsQuote  «empty»] = “”
StringValue[OrdinaryStringCharsQuote  StringCharsQuote PlainStringChar]
  = StringValue[StringCharsQuote]  [CharacterValue[PlainStringChar]]
StringValue[OrdinaryStringCharsQuote  StringCharsQuote PlainStringQuoteQuote]
  = StringValue[StringCharsQuote]  [CharacterValue[PlainStringQuoteQuote]]
StringValue[OrdinaryStringCharsQuote  OrdinaryStringCharsQuote1 OctalDigit]
  = StringValue[OrdinaryStringCharsQuote1]  [CharacterValue[OctalDigit]]
StringValue[OrdinaryStringCharsQuote  StringCharsQuote \ OrdinaryEscape]
  = StringValue[StringCharsQuote]  [CharacterValue[OrdinaryEscape]]
action CharacterValue[PlainStringChar] : Character = PlainStringChar
action CharacterValue[PlainStringQuoteQuote] : Character
CharacterValue[PlainStringQuotesingle  "] = ‘"’
CharacterValue[PlainStringQuotedouble  '] = ‘'’
Syntax
OrdinaryEscape 
	StringCharEscape
|	FullOctalEscape
|	HexEscape
|	UnicodeEscape
|	StringNonEscape
StringNonEscape  NonTerminator except OctalDigit | x | u | ' | " | \ | b | f | n | r | t | v
Semantics
action CharacterValue[OrdinaryEscape] : Character
CharacterValue[OrdinaryEscape  StringCharEscape] = CharacterValue[StringCharEscape]
CharacterValue[OrdinaryEscape  FullOctalEscape] = CharacterValue[FullOctalEscape]
CharacterValue[OrdinaryEscape  HexEscape] = CharacterValue[HexEscape]
CharacterValue[OrdinaryEscape  UnicodeEscape] = CharacterValue[UnicodeEscape]
CharacterValue[OrdinaryEscape  StringNonEscape] = CharacterValue[StringNonEscape]
action CharacterValue[StringNonEscape] : Character = StringNonEscape
Syntax
StringCharEscape 
	'
|	"
|	\
|	b
|	f
|	n
|	r
|	t
|	v
Semantics
action CharacterValue[StringCharEscape] : Character
CharacterValue[StringCharEscape  '] = ‘'’
CharacterValue[StringCharEscape  "] = ‘"’
CharacterValue[StringCharEscape  \] = ‘\’
CharacterValue[StringCharEscape  b] = ‘«BS»’
CharacterValue[StringCharEscape  f] = ‘«FF»’
CharacterValue[StringCharEscape  n] = ‘«LF»’
CharacterValue[StringCharEscape  r] = ‘«CR»’
CharacterValue[StringCharEscape  t] = ‘«TAB»’
CharacterValue[StringCharEscape  v] = ‘«VT»’
Syntax
ShortOctalEscape 
	OctalDigit
|	ZeroToThree OctalDigit
FullOctalEscape 
	FourToSeven OctalDigit
|	ZeroToThree OctalDigit OctalDigit
ZeroToThree  0 | 1 | 2 | 3
FourToSeven  4 | 5 | 6 | 7
HexEscape  x HexDigit HexDigit
UnicodeEscape  u HexDigit HexDigit HexDigit HexDigit
Semantics
action CharacterValue[ShortOctalEscape] : Character
CharacterValue[ShortOctalEscape  OctalDigit] = codeToCharacter(OctalValue[OctalDigit])
CharacterValue[ShortOctalEscape  ZeroToThree OctalDigit]
  = codeToCharacter(8*OctalValue[ZeroToThree] + OctalValue[OctalDigit])
action CharacterValue[FullOctalEscape] : Character
CharacterValue[FullOctalEscape  FourToSeven OctalDigit]
  = codeToCharacter(8*OctalValue[FourToSeven] + OctalValue[OctalDigit])
CharacterValue[FullOctalEscape  ZeroToThree OctalDigit1 OctalDigit2]
  = codeToCharacter(
         64*OctalValue[ZeroToThree] + 8*OctalValue[OctalDigit1] + OctalValue[OctalDigit2])
action DigitValue[ZeroToThree] : Integer = digitValue(ZeroToThree)
action DigitValue[FourToSeven] : Integer = digitValue(FourToSeven)
action CharacterValue[HexEscape] : Character
CharacterValue[HexEscape  x HexDigit1 HexDigit2]
  = codeToCharacter(16*HexValue[HexDigit1] + HexValue[HexDigit2])
action CharacterValue[UnicodeEscape] : Character
CharacterValue[UnicodeEscape  u HexDigit1 HexDigit2 HexDigit3 HexDigit4]
  = codeToCharacter(
         4096*HexValue[HexDigit1] + 256*HexValue[HexDigit2] + 16*HexValue[HexDigit3] +
         HexValue[HexDigit4])