Language rules from the ECMAScript Language Specification
(Edition 3 Final)

24 March 2000


-------------------------------

InputElementDiv ::
	WhiteSpace
	IgnoredCaharacter
	LineTerminator
	Comment
	Token
	DivPunctuator


InputElementRegExp ::
	WhiteSpace
	IgnoredCaharacter
	LineTerminator
	Comment
	Token
	RegularExpressionLiteral

WhiteSpace ::
	\u0009	<TAB>
	\u000B	<VT>
	\u000C	<FF>
	\u0020	<SP>
	\u00A0	<NBSP>
	OtherUnicodeSpaceSeparator	<USP>
		(i.e. \u2000 to \u200B and \u3000)


[ignored unless escaped]
IgnoredCaharacter ::
	LEFT-TO-RIGHT MARK
	RIGHT-TO-LEFT MARK
	OtherUnicodeFormattingMarks


LineTerminators ::
	\u000A	<LF>
	\u000D	<CR>
	\u0085	?
	\u2028	<LS>
	\u2029	<PS>


[considered as a space or a line terminator]
Comment ::
	MultiLineComment
	SingleLineComment


[if a line terminator is included, then the
comment becomes a line terminator, otherwise
it is a white space]
MultiLineComment ::
	'/*' MultiLineCommentChars/opt '*/'

MultiLineCommentChars ::
	MultiLineNotAsteriskChar MultiLineCommentChars/opt
	'*' PostAsteriskCommentChars/opt

PostAsteriskCommentChars ::
	MultiLineNotForwardSlashOrAsteriskChar MultiLineCommentChars/opt
	'*' PostAsteriskCommentChars/opt

MultiLineNotAsteriskChar ::
	SourceCharacter BUT NOT asterisk '*'


MultiLineNotForwardSlashOrAsteriskChar ::
	SourceCharacter BUT NOT forward-slash '/' or asterisk '*'


[a single comment line is always considered
as a line terminator (even if at the end of
a file and no line terminator is found?)]
SingleLineComment ::
	'//' SingleLineCommentChars/opt


SingleLineCommentChars ::
	SingleLineCommentChar SingleLineCommentChars/opt

SingleLineCommentChar ::
	SourceCharacter BUT NOT LineTerminator



Tokens ::
	ReservedWord
	Identifier
	Punctuator
	NumericLiteral
	StringLiteral


ReservedWord ::
	Keyword
	FutureReservedWord
	NullLiteral
	BooleanLiteral


Keyword ::
	'break'
	'case'
	'catch'
	'continue'
	'default'
	'delete'
	'do'
	'else'
	'finally'
	'for'
	'function'
	'if'
	'in'
	'instanceof'
	'new'
	'return'
	'switch'
	'this'
	'throw'
	'try'
	'typeof'
	'var'
	'void'
	'while'
	'with'


FutureReservedWord ::
	'abstract'
	'boolean'
	'byte'
	'char'
	'class'
	'const'
	'debugger'
	'double'
	'enum'
	'export'
	'extends'
	'final'
	'float'
	'goto'
	'implements'
	'import'
	'int'
	'interface'
	'long'
	'native'
	'package'
	'private'
	'protected'
	'public'
	'short'
	'static'
	'super'
	'synchronized'
	'throws'
	'transient'
	'volatile'



Identifier ::
	IdentifierName BUT NOT ReservedWord


IdentifierName ::
	IdentifierStart
	IdentifierName IdentifierPart


[identifiers starting with a '$' sign are reserved
for automatic code generators]
IdentifierStart ::
	UnicodeLetter
	'$'
	'_'
	'\' UnicodeEscapeSequence

IdentifierPart ::
	IdentifierStart
	UnicodeCombiningMark
	UnicodeDigit
	UnicodeConnectorPunctuation
	'\' UnicodeEscapeSequence

UnicodeLetter ::
	any character in the Unicode categories:
		"Uppercase letter (Lu)"
		"Lowercase letter (Ll)"
		"Titlecase letter (Lt)"
		"Modifier letter (Lm)"
		"Other letter (Lo)"
		"Letter number (Nl)"


UnicodeCombiningMark ::
	any character in the Unicode categories:
		"Non-spacing mark (Mn)"
		"Combining spacing mark (Mc)"


UnicodeDigit ::
	any character in the Unicode category:
		"Decimal number (Nd)"


UnicodeConnectorPunctuation ::
	any character in the Unicode category:
		"Connector punctuation (Pc)"




HexDigit ::
	[0-9A-Fa-f]


Punctuator ::
	'{'
	'}'
	'('
	')'
	'['
	']'
	'.'
	';'
	','
	'<'
	'>'
	'<='
	'>='
	'=='
	'!='
	'==='
	'!=='
	'+'
	'-'
	'*'
	'%'
	'++'
	'--'
	'<<'
	'>>'
	'>>>'
	'&'
	'|'
	'^'
	'!'
	'~'
	'&&'
	'||'
	'?'
	':'
	'='
	'+='
	'-='
	'*='
	'%='
	'<<='
	'>>='
	'>>>='
	'&='
	'|='
	'^='

DivPunctuator ::
	'/'
	'/='


Literal ::
	NullLiteral
	BooleanLiteral
	NumericLiteral
	StringLiteral


NullLiteral ::
	'null'


BooleanLiteral ::
	'true'
	'false'


[a NumericLiteral can't be followed by an
IdentifierStart nor a DecimalDigit]
NumericLiteral ::
	DecimalLiteral
	HexIntegerLiteral
	[to support old scripts]
	OctalIntegerLiteral

[the octal entry is only to support old scripts]
OctalIntegerLiteral ::
	'0' OctalDigit
	OctalIntegerLiteral OctalDigit

DecimalLiteral ::
	DecimalIntegerLiteral '.' DecimalDigit/opt ExponentPart/opt
	'.' DecimalDigits ExponentPart/opt
	DecimalIntegerLiteral ExponentPart/opt

DecimalIntegerLiteral ::
	0
	NonZeroDigit DecimalDigits/opt

DecimalDigits ::
	DecimalDigit
	DecimalDigits DecimalDigit

OctalDigit ::
	[0-7]

DecimalDigit ::
	[0-9]

NonZeroDigit ::
	[1-9]

ExponentPart ::
	ExponentIndicator SignedInteger

ExponentIndicator ::
	'e'
	'E'

SignedInteger ::
	DecimalDigits
	'+' DecimalDigits
	'-' DecimalDigits

HexIntegerLiteral ::
	'0x' HexDigit
	'0X' HexDigit
	HexIntegerLiteral HexDigit


StringLiteral ::
	'"' DoubleStringCharacters/opt '"'
	''' SingleStringCharacters/opt '''

DoubleStringCharacters ::
	DoubleStringCharacter DoubleStringCharacters/opt

SingleStringCharacters ::
	SingleStringCharacter SingleStringCharacters/opt

DoubleStringCharacter ::
	SourceCharacter BUT NOT double quote '"' or backslash '\' or LineTerminator
	'\' EscapeSequence

SingleStringCharacter ::
	SourceCharacter BUT NOT single quote ''' or backslash '\' or LineTerminator
	'\' EscapeSequence

EscapeSequence ::
	CharacterEscapeSequence
	0 [lookahead NOT DecimalDigit]
	HexEscapeSequence
	UnicodeEscapeSequence
	OctalEscapeSequence [for old scripts support]

[older scripts may include octal sequences]
OctalEscapeSequence ::
	OctalDigit [lookahead NOT DecimalDigit]
	ZeroToThree OctalDigit [lookahead NOT DecimalDigit]
	FourToSeven OctalDigit
	ZeroToThree OctalDigit OctalDigit

ZeroToThree ::
	[0-3]

FourToSeven ::
	[4-7]


CharacterEscapeSequence ::
	SingleEscapeCharacter
	NonEscapeCharacter

SingleEscapeCharacter ::
	'''
	'"'
	'\'
	'b'
	'f'
	'n'
	'r'
	't'
	'v'

NonEscapeCharacter ::
	SourceCharacter BUT NOT EscapeCharacter or LineTerminator

EscapeCharacter ::
	SingleEscapeCharacter
	DecimalDigit
	'x'
	'u'

HexEscapeSequence ::
	'x' HexDigit HexDigit

UnicodeEscapeSequence ::
	'u' HexDigit HexDigit HexDigit HexDigit


[no empty regular expressions allowed; use /(?:)/ instead]
RegularExpressionLiteral ::
	'/' RegularExpressionBody '/' RegularExpressionFlags/opt

RegularExpressionBody ::
	RegularExpressionFirstChar RegularExpressionChars/opt

RegularExpressionChars ::
	RegularExpressionChars RegularExpressionChar

RegularExpressionFirstChar ::
	NonTerminator BUT NOT '*' or '\' or '.'
	BackslashSequence

RegularExpressionChar ::
	NonTerminator BUT NOT '\' or '/'
	BackslashSequence

BlackslashSequence ::
	'\' NonTerminator

NonTerminator ::
	SourceCharacter BUT NOT LineTerminator

RegularExpressionFlags ::
	RegularExpressionFlags IdentifierPart


[automatic semicolon insertion: this happens when
(a) an offending token is found after a LineTerminator
or the token is '}', (b) the end of the input stream
is found and no ';' was found, (c) a production was defined
as a 'restricted production' such as "no LineTermintor here"]

[The automatic semicolon is NOT applied if the result
is the empty statement or one of the semicolon of
the for() statement]

Restricted productions:

	PostfixExpression
	ContinueStatement
	BreakStatement
	ReturnStatement
	ThrowStatement



SourceCharacter ::
	any Unicode character



PrimaryExpression ::
	'this'
	Identifier
	Literal
	ArrayLiteral
	ObjectLiteral
	'(' Expression ')'


ArrayLiteral ::
	'[' Elision/opt ']'
	'[' ElementList ']'
	'[' ElementList ',' Elision/opt ']'

[can be simplified to:]
ArrayLiteral ::
	'[' Elision/opt ']'
	'[' ElementList Elision/opt ']'


ElementList ::
	Elision/opt AssignmentExpression
	ElementList ',' Elision/opt AssignmentExpression

Elision ::
	','
	Elision ','



ObjectLiteral ::
	'{' PropertyNameAndValueList/opt '}'

PropertyNameAndValueList ::
	PropertyName ':' AssignmentExpression
	PropertyNameAndValueList ',' PropertyName ':' AssignmentExpression

PropetyName ::
	Identifier
	StringLiteral
	NumericLiteral


MemberExpression ::
	PrimaryExpression
	FunctionExpression
	MemberExpression '[' Expression ']'
	MemberExpression '.' Identifier
	'new' MemberExpression Arguments

NewExpression ::
	MemberExpression
	'new' NewExpression

CallExpression ::
	MemberExpression Arguments
	CallExpression Arguments
	CallExpression '[' Expression ']'
	CallExpression '.' Identifier

Arguemnts ::
	'(' ArgumentList/opt ')'

ArgumentList ::
	AssignmentExpression
	ArgumentList ',' AssignmentExpression

LeftHandSideExpression ::
	NewExpression
	CallExpression


PostfixExpression ::
	LeftHandSideExpression
	LeftHandSideExpression [no LineTerminator here] '++'
	LeftHandSideExpression [no LineTerminator here] '--'


UnaryExpression ::
	PostfixExpression
	'delete' UnaryExpression
	'void' UnaryExpression
	'typeof' UnaryExpression
	'++' UnaryExpression
	'--' UnaryExpression
	'+' UnaryExpression
	'-' UnaryExpression
	'~' UnaryExpression
	'!' UnaryExpression


['void' returns 'undefined']
['typeof' returns one of "undefined", "oject", "boolean",
"number", "string", "function", <implementation dependent>]



MultiplicativeExpression ::
	UnaryExpression
	MultiplicativeExpression '*' UnaryExpression
	MultiplicativeExpression '/' UnaryExpression
	MultiplicativeExpression '%' UnaryExpression


AdditiveExpression ::
	MultiplicativeExpression
	AdditiveExpression '+' MultiplicativeExpression
	AdditiveExpression '-' MultiplicativeExpression

ShiftExpression ::
	AdditiveExpression
	ShiftExpression '<<' AdditiveExpression
	ShiftExpression '>>' AdditiveExpression
	ShiftExpression '>>>' AdditiveExpression

RelationalExpression ::
	ShiftExpression
	RelationalExpression '<' ShiftExpression
	RelationalExpression '>' ShiftExpression
	RelationalExpression '<=' ShiftExpression
	RelationalExpression '>=' ShiftExpression
	RelationalExpression 'instanceof' ShiftExpression
	RelationalExpression 'in' ShiftExpression

RelationalExpressionNoIn ::
	ShiftExpression
	RelationalExpressionNoIn '<' ShiftExpression
	RelationalExpressionNoIn '>' ShiftExpression
	RelationalExpressionNoIn '<=' ShiftExpression
	RelationalExpressionNoIn '>=' ShiftExpression
	RelationalExpressionNoIn 'instanceof' ShiftExpression


EqualityExpression ::
	RelationalExpression
	EqualityExpression '==' RelationalExpression
	EqualityExpression '!=' RelationalExpression
	EqualityExpression '===' RelationalExpression
	EqualityExpression '!==' RelationalExpression

EqualityExpressionNoIn ::
	RelationalExpressionNoIn
	EqualityExpressionNoIn '==' RelationalExpressionNoIn
	EqualityExpressionNoIn '!=' RelationalExpressionNoIn
	EqualityExpressionNoIn '===' RelationalExpressionNoIn
	EqualityExpressionNoIn '!==' RelationalExpressionNoIn


BitwiseANDExpression ::
	EqualityExpression
	BitwiseANDExpression '&' EqualityExpression

BitwiseANDExpressionNoIn ::
	EqualityExpressionNoIn
	BitwiseANDExpressionNoIn '&' EqualityExpressionNoIn

BitwiseXORExpression ::
	BitwsieANDExpression
	BitwiseXORExpression '^' BitwsieANDExpression

BitwiseXORExpressionNoIn ::
	BitwsieANDExpressionNoIn
	BitwiseXORExpressionNoIn '^' BitwsieANDExpressionNoIn

BitwiseORExpression ::
	BitwsieXORExpression
	BitwiseORExpression '^' BitwsieXORExpression

BitwiseORExpressionNoIn ::
	BitwsieXORExpressionNoIn
	BitwiseORExpressionNoIn '^' BitwsieXORExpressionNoIn



LogicalANDExpression ::
	BitwiseORExpression
	LogicalANDExpression '&&' BitwiseORExpression

LogicalANDExpressionNoIn ::
	BitwiseORExpressionNoIn
	LogicalANDExpressionNoIn '&&' BitwiseORExpressionNoIn


LogicalORExpression ::
	LogicalANDExpression
	LogicalORExpression '||' LogicalANDExpression

LogicalORExpressionNoIn ::
	LogicalANDExpressioNoIn
	LogicalORExpressionNoIn '||' LogicalANDExpressioNoIn



ConditionalExpression ::
	LogicalORExpression
	LogicalORExpression '?' AssignmentExpression ':' AssignmentExpression

ConditionalExpressionNoIn ::
	LogicalORExpressionNoIn
	LogicalORExpressionNoIn '?' AssignmentExpression ':' AssignmentExpressionNoIn


AssignmentExpression ::
	ConditionalExpression
	LeftHandSideExpression AssignmentOperator AssignmentExpression

AssignmentExpressionNoIn ::
	ConditionalExpressionNoIn
	LeftHandSideExpression AssignmentOperator AssignmentExpressionNoIn

AssignmentOperator ::
	'='
	'*='
	'/='
	'%='
	'+='
	'-='
	'<<='
	'>>='
	'>>>='
	'&='
	'^='
	'|='

Expression ::
	AssignmentExpression
	Expression ',' AssignmentExpression

ExpresionNoIn ::
	AssignmentExpressionNoIn
	ExpressionNoIn ',' AssignmentExpressionNoIn






Statement ::
	Block
	VariableStatement
	EmptyStatement
	ExpressionStatement
	IfStatement
	IterationStatement
	ContinueStatement
	BreakStatement
	ReturnStatement
	WithStatement
	LabelledStatement
	SwitchStatement
	ThrowStatement
	TryStatement


Block ::
	'{' StatementList/opt '}'

StatementList ::
	Statement
	StatementList Statement

VariableStatement::
	'var' VariableDeclarationList ';'

VariableDeclarationList ::
	VariableDeclaration
	VariableDeclarationList ',' VariableDeclaration

VariableDeclarationListNoIn ::
	VariableDeclarationNoIn
	VariableDeclarationListNoIn ',' VariableDeclarationNoIn

VariableDeclaration ::
	Identifier Initializer/opt

VariableDeclarationNoIn ::
	Identifier InitializerNoIn/opt

Initializer ::
	'=' AssignmentExpression

InitializerNoIn ::
	'=' AssignmentExpressionNoIn



EmptyStatement ::
	';'


ExpressionStatement ::
	Expression ';' BUT NOT '{' or 'function'



IfStatement ::
	'if' '(' Expression ')' Statement 'else' Statement
	'if' '(' Expression ')' Statement


IterationStatement ::
	'do' Statement 'while' '(' Expression ')' ';'
	'while' '(' Expression ')' statement
	'for' '(' ExpressionNoIn/opt ';' ExpressionNoIn/opt ';' ExpressionNoIn/opt ')' Statement
	'for' '(' 'var' VariableDeclarationListNoIn ';' ExpressionNoIn/opt ';' ExpressionNoIn/opt ')' Statement
	'for' '(' LeftHandSideExpression 'in' Expression ')' Statement
	'for' '(' 'var' VariableDeclarationListNoIn 'in' Expression ')' Statement



ContinueStatement ::
	'continue' [no LineTerminator here] Identifier/opt ';'

BreakStatement ::
	'break' [no LineTerminator here] Identifier/opt ';'


ReturnStatement ::
	'return' [no LineTerminator here] Expression/opt ';'


WithStatement ::
	'with' '(' Expression ')' Statement


SwitchStatement ::
	'switch' '(' Expression ')' CaseBlock

CaseBlock ::
	'{' CaseClauses/opt '}'
	'{' CaseClauses/opt DefaultClause CaseClauses/opt '}'

CaseClauses ::
	CaseClause
	CaseClauses CaseClause

CaseClause ::
	'case' Expression ':' StatementList/opt

DefaultClause ::
	'default' ':' StatementList/opt


LabelledStatement ::
	Identifier ':' Statement



ThrowStatement ::
	'throw' [no LineTerminator here] Expression ';'



TryStatement ::
	'try' Block Catch
	'try' Block Finally
	'try' Block Catch Finally

Catch ::
	'catch' '(' Identifier ')' Block

Finally ::
	'finally' Block



FunctionDeclaration ::
	'function' Identifier '(' FormalParameterList/opt ')' '{' FunctionBody '}'

FunctionExpression ::
	'function' Identifier/opt '(' FormalParameterList/opt ')' '{' FunctionBody '}'


FormalParameterList ::
	Identifier
	FormalParameterList ',' Identifier

FunctionBody ::
	SourceElements



Program ::
	SourceElements

SourceElements ::
	SourceElement
	SourceElements SourceElement

SourceElement ::
	Statement
	FunctionDeclaration



[we may offer as much syntax check as we want at
compile time -- that is, on top of the minimum
requirements]

[we may have additional types, values, objects,
properties and functions]




[number conversion -- only necessary if we want to
check strings which we know are to be converted to numbers]

StringNumericLiteral ::
	StrWhiteSpace/opt
	StrWhiteSpace/opt StrNumericLiteral StrWhiteSpace/opt

StrWhiteSpace ::
	StrWhiteSpaceChar StrWhiteSpace/opt

StrWhiteSpaceChar ::
	<TAB>
	<SP>
	<NBSP>
	<FF>
	<VT>
	<CR>
	<LF>
	<LS>
	<PS>
	<USP>

StrNumericLiteral ::
	StrDecimalLiteral
	HexIntegerLiteral

StrDecimalLiteral ::
	StrUnsignedDecimalLiteral
	'+' StrUnsignedDecimalLiteral
	'-' StrUnsignedDecimalLiteral

StrUnsignedDecimalLiteral ::
	'Infinity'
	DecimalDigits '.' DecimalDigits/opt ExponentPart/opt
	'.' DecimalDigits ExponentPart/opt
	DecimalDigits ExponentPart/opt




