Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

1187 lines (980 sloc) 57.416 kb
{
module Language.JavaScript.Parser.Grammar5 (
parseProgram
, parseLiteral
, parsePrimaryExpression
, parseStatement
-- debug
, fp
) where
-- import Control.Monad.Error.Class (throwError)
import Data.Char
import Language.JavaScript.Parser.Lexer
import Language.JavaScript.Parser.ParseError
import Language.JavaScript.Parser.ParserMonad
import Language.JavaScript.Parser.SrcLocation
import Language.JavaScript.Parser.Token
import qualified Language.JavaScript.Parser.AST as AST
}
-- The name of the generated function to be exported from the module
%name parseProgram Program
%name parseLiteral LiteralMain
%name parsePrimaryExpression PrimaryExpressionMain
%name parseStatement StatementMain
%tokentype { Token }
%error { parseError }
%monad { Alex } { >>= } { return }
%lexer { lexCont } { EOFToken {} }
%token
';' { SemiColonToken {} }
',' { CommaToken {} }
'?' { HookToken {} }
':' { ColonToken {} }
'||' { OrToken {} }
'&&' { AndToken {} }
'|' { BitwiseOrToken {} }
'^' { BitwiseXorToken {} }
'&' { BitwiseAndToken {} }
'===' { StrictEqToken {} }
'==' { EqToken {} }
'=' { SimpleAssignToken {} }
'!==' { StrictNeToken {} }
'!=' { NeToken {} }
'<<' { LshToken {} }
'<=' { LeToken {} }
'<' { LtToken {} }
'>>>' { UrshToken {} }
'>>' { RshToken {} }
'>=' { GeToken {} }
'>' { GtToken {} }
'++' { IncrementToken {} }
'--' { DecrementToken {} }
'+' { PlusToken {} }
'-' { MinusToken {} }
'*' { MulToken {} }
'/' { DivToken {} }
'%' { ModToken {} }
'!' { NotToken {} }
'~' { BitwiseNotToken {} }
'.' { DotToken {} }
'[' { LeftBracketToken {} }
']' { RightBracketToken {} }
'{' { LeftCurlyToken {} }
'}' { RightCurlyToken {} }
'(' { LeftParenToken {} }
')' { RightParenToken {} }
'@*/' { CondcommentEndToken {} }
'break' { BreakToken {} }
'case' { CaseToken {} }
'catch' { CatchToken {} }
'const' { ConstToken {} }
'continue' { ContinueToken {} }
'debugger' { DebuggerToken {} }
'default' { DefaultToken {} }
'delete' { DeleteToken {} }
'do' { DoToken {} }
'else' { ElseToken {} }
'enum' { EnumToken {} }
'false' { FalseToken {} }
'finally' { FinallyToken {} }
'for' { ForToken {} }
'function' { FunctionToken {} }
'get' { GetToken {} }
'if' { IfToken {} }
'in' { InToken {} }
'instanceof' { InstanceofToken {} }
'new' { NewToken {} }
'null' { NullToken {} }
'return' { ReturnToken {} }
'set' { SetToken {} }
'switch' { SwitchToken {} }
'this' { ThisToken {} }
'throw' { ThrowToken {} }
'true' { TrueToken {} }
'try' { TryToken {} }
'typeof' { TypeofToken {} }
'var' { VarToken {} }
'void' { VoidToken {} }
'while' { WhileToken {} }
'with' { WithToken {} }
'ident' { IdentifierToken {} }
'decimal' { DecimalToken {} }
'hexinteger' { HexIntegerToken {} }
'octal' { OctalToken {} }
'string' { StringToken {} }
'regex' { RegExToken {} }
'assign' { AssignToken {} }
'future' { FutureToken {} }
'tail' { TailToken {} }
'eof' { EOFToken {} }
%%
-- ---------------------------------------------------------------------
-- Sort out automatically inserted semi-colons
AutoSemi :: { AST.JSNode }
AutoSemi : ';' { AST.NT (AST.JSLiteral ";") (ss $1) (gc $1)}
| { AST.NT (AST.JSLiteral "") tokenPosnEmpty []}
-- ---------------------------------------------------------------------
-- Helpers
LParen :: { AST.JSNode }
LParen : '(' { fp (AST.NT (AST.JSLiteral "(") (ss $1) (gc $1))}
RParen :: { AST.JSNode }
RParen : ')' { fp (AST.NT (AST.JSLiteral ")") (ss $1) (gc $1))}
LBrace :: { AST.JSNode }
LBrace : '{' { fp (AST.NT (AST.JSLiteral "{") (ss $1) (gc $1))}
RBrace :: { AST.JSNode }
RBrace : '}' { fp (AST.NT (AST.JSLiteral "}") (ss $1) (gc $1))}
LSquare :: { AST.JSNode }
LSquare : '[' { fp (AST.NT (AST.JSLiteral "[") (ss $1) (gc $1))}
RSquare :: { AST.JSNode }
RSquare : ']' { fp (AST.NT (AST.JSLiteral "]") (ss $1) (gc $1))}
Comma :: { AST.JSNode }
Comma : ',' { fp (AST.NT (AST.JSLiteral ",") (ss $1) (gc $1))}
Colon :: { AST.JSNode }
Colon : ':' { fp (AST.NT (AST.JSLiteral ":") (ss $1) (gc $1))}
Semi :: { AST.JSNode }
Semi : ';' { fp (AST.NT (AST.JSLiteral ";") (ss $1) (gc $1))}
Dot :: { AST.JSNode }
Dot : '.' { fp (AST.NT (AST.JSLiteral ".") (ss $1) (gc $1))}
Increment :: { AST.JSNode }
Increment : '++' { fp (AST.NT (AST.JSLiteral "++") (ss $1) (gc $1))}
Decrement :: { AST.JSNode }
Decrement : '--' { fp (AST.NT (AST.JSLiteral "--") (ss $1) (gc $1))}
Delete :: { AST.JSNode }
Delete : 'delete' { fp (AST.NT (AST.JSLiteral "delete") (ss $1) (gc $1))}
Void :: { AST.JSNode }
Void : 'void' { fp (AST.NT (AST.JSLiteral "void") (ss $1) (gc $1))}
Typeof :: { AST.JSNode }
Typeof : 'typeof' { fp (AST.NT (AST.JSLiteral "typeof") (ss $1) (gc $1))}
Plus :: { AST.JSNode }
Plus : '+' { fp (AST.NT (AST.JSLiteral "+") (ss $1) (gc $1))}
Minus :: { AST.JSNode }
Minus : '-' { fp (AST.NT (AST.JSLiteral "-") (ss $1) (gc $1))}
Tilde :: { AST.JSNode }
Tilde : '~' { fp (AST.NT (AST.JSLiteral "~") (ss $1) (gc $1))}
Not :: { AST.JSNode }
Not : '!' { fp (AST.NT (AST.JSLiteral "!") (ss $1) (gc $1))}
Mul :: { AST.JSNode }
Mul : '*' { fp (AST.NT (AST.JSLiteral "*") (ss $1) (gc $1))}
Div :: { AST.JSNode }
Div : '/' { fp (AST.NT (AST.JSLiteral "/") (ss $1) (gc $1))}
Mod :: { AST.JSNode }
Mod : '%' { fp (AST.NT (AST.JSLiteral "%") (ss $1) (gc $1))}
Lsh :: { AST.JSNode }
Lsh : '<<' { fp (AST.NT (AST.JSLiteral "<<") (ss $1) (gc $1))}
Rsh :: { AST.JSNode }
Rsh : '>>' { fp (AST.NT (AST.JSLiteral ">>") (ss $1) (gc $1))}
Ursh :: { AST.JSNode }
Ursh : '>>>' { fp (AST.NT (AST.JSLiteral ">>>") (ss $1) (gc $1))}
Le :: { AST.JSNode }
Le : '<=' { fp (AST.NT (AST.JSLiteral "<=") (ss $1) (gc $1))}
Lt :: { AST.JSNode }
Lt : '<' { fp (AST.NT (AST.JSLiteral "<") (ss $1) (gc $1))}
Ge :: { AST.JSNode }
Ge : '>=' { fp (AST.NT (AST.JSLiteral ">=") (ss $1) (gc $1))}
Gt :: { AST.JSNode }
Gt : '>' { fp (AST.NT (AST.JSLiteral ">") (ss $1) (gc $1))}
In :: { AST.JSNode }
In : 'in' { fp (AST.NT (AST.JSLiteral "in") (ss $1) (gc $1))}
Instanceof :: { AST.JSNode }
Instanceof : 'instanceof' { fp (AST.NT (AST.JSLiteral "instanceof") (ss $1) (gc $1))}
StrictEq :: { AST.JSNode }
StrictEq : '===' { fp (AST.NT (AST.JSLiteral "===") (ss $1) (gc $1))}
Equal :: { AST.JSNode }
Equal : '==' { fp (AST.NT (AST.JSLiteral "==") (ss $1) (gc $1))}
StrictNe :: { AST.JSNode }
StrictNe : '!==' { fp (AST.NT (AST.JSLiteral "!==") (ss $1) (gc $1))}
Ne :: { AST.JSNode }
Ne : '!=' { fp (AST.NT (AST.JSLiteral "!=") (ss $1) (gc $1))}
Or :: { AST.JSNode }
Or : '||' { fp (AST.NT (AST.JSLiteral "||") (ss $1) (gc $1))}
And :: { AST.JSNode }
And : '&&' { fp (AST.NT (AST.JSLiteral "&&") (ss $1) (gc $1))}
BitOr :: { AST.JSNode }
BitOr : '|' { fp (AST.NT (AST.JSLiteral "|") (ss $1) (gc $1))}
BitAnd :: { AST.JSNode }
BitAnd : '&' { fp (AST.NT (AST.JSLiteral "&") (ss $1) (gc $1))}
BitXor :: { AST.JSNode }
BitXor : '^' { fp (AST.NT (AST.JSLiteral "^") (ss $1) (gc $1))}
Hook :: { AST.JSNode }
Hook : '?' { fp (AST.NT (AST.JSLiteral "?") (ss $1) (gc $1))}
SimpleAssign :: { AST.JSNode }
SimpleAssign : '=' { fp (AST.NT (AST.JSLiteral "=") (ss $1) (gc $1))}
Assign :: { AST.JSNode }
Assign : 'assign' { fp (AST.NT (AST.JSLiteral (token_literal $1)) (ss $1) (gc $1))}
Var :: { AST.JSNode }
Var : 'var' { fp (AST.NT (AST.JSLiteral "var") (ss $1) (gc $1))}
Const :: { AST.JSNode }
Const : 'const' { fp (AST.NT (AST.JSLiteral "const") (ss $1) (gc $1))}
If :: { AST.JSNode }
If : 'if' { fp (AST.NT (AST.JSLiteral "if") (ss $1) (gc $1))}
Else :: { AST.JSNode }
Else : 'else' { fp (AST.NT (AST.JSLiteral "else") (ss $1) (gc $1))}
Do :: { AST.JSNode }
Do : 'do' { fp (AST.NT (AST.JSLiteral "do") (ss $1) (gc $1))}
While :: { AST.JSNode }
While : 'while' { fp (AST.NT (AST.JSLiteral "while") (ss $1) (gc $1))}
For :: { AST.JSNode }
For : 'for' { fp (AST.NT (AST.JSLiteral "for") (ss $1) (gc $1))}
Continue :: { AST.JSNode }
Continue : 'continue' { fp (AST.NT (AST.JSLiteral "continue") (ss $1) (gc $1))}
Break :: { AST.JSNode }
Break : 'break' { fp (AST.NT (AST.JSLiteral "break") (ss $1) (gc $1))}
Return :: { AST.JSNode }
Return : 'return' { fp (AST.NT (AST.JSLiteral "return") (ss $1) (gc $1))}
With :: { AST.JSNode }
With : 'with' { fp (AST.NT (AST.JSLiteral "with") (ss $1) (gc $1))}
Switch :: { AST.JSNode }
Switch : 'switch' { fp (AST.NT (AST.JSLiteral "switch") (ss $1) (gc $1))}
Case :: { AST.JSNode }
Case : 'case' { fp (AST.NT (AST.JSLiteral "case") (ss $1) (gc $1))}
Default :: { AST.JSNode }
Default : 'default' { fp (AST.NT (AST.JSLiteral "default") (ss $1) (gc $1))}
Throw :: { AST.JSNode }
Throw : 'throw' { fp (AST.NT (AST.JSLiteral "throw") (ss $1) (gc $1))}
Try :: { AST.JSNode }
Try : 'try' { fp (AST.NT (AST.JSLiteral "try") (ss $1) (gc $1))}
CatchL :: { AST.JSNode }
CatchL : 'catch' { fp (AST.NT (AST.JSLiteral "catch") (ss $1) (gc $1))}
FinallyL :: { AST.JSNode }
FinallyL : 'finally' { fp (AST.NT (AST.JSLiteral "finally") (ss $1) (gc $1))}
Function :: { AST.JSNode }
Function : 'function' { fp (AST.NT (AST.JSLiteral "function") (ss $1) (gc $1))}
Eof :: { AST.JSNode }
Eof : 'tail' { fp (AST.NT (AST.JSLiteral "") (ss $1) (gc $1))}
-- Literal :: See 7.8
-- NullLiteral
-- BooleanLiteral
-- NumericLiteral
-- StringLiteral
Literal :: { AST.JSNode }
Literal : NullLiteral {$1}
| BooleanLiteral {$1}
| NumericLiteral {$1}
| StringLiteral {$1}
| RegularExpressionLiteral {$1}
NullLiteral :: { AST.JSNode }
NullLiteral : 'null' { fp (AST.NT (AST.JSLiteral "null") (ss $1) (gc $1))}
BooleanLiteral :: { AST.JSNode }
BooleanLiteral : 'true' { fp (AST.NT (AST.JSLiteral "true") (ss $1) (gc $1)) }
| 'false' { fp (AST.NT (AST.JSLiteral "false") (ss $1) (gc $1)) }
-- <Numeric Literal> ::= DecimalLiteral
-- | HexIntegerLiteral
-- | OctalLiteral
NumericLiteral :: { AST.JSNode }
NumericLiteral : 'decimal' { fp (AST.NT (AST.JSDecimal (token_literal $1)) (ss $1) (gc $1))}
| 'hexinteger' { fp (AST.NT (AST.JSHexInteger (token_literal $1)) (ss $1) (gc $1)) }
| 'octal' { fp (AST.NT (AST.JSOctal (token_literal $1)) (ss $1) (gc $1)) }
StringLiteral :: { AST.JSNode }
StringLiteral : 'string' { fp (AST.NT (AST.JSStringLiteral (token_delimiter $1) (token_literal $1)) (ss $1) (gc $1)) }
-- <Regular Expression Literal> ::= RegExp
RegularExpressionLiteral :: { AST.JSNode }
RegularExpressionLiteral : 'regex' { fp (AST.NT (AST.JSRegEx (token_literal $1)) (ss $1) (gc $1)) }
-- PrimaryExpression : See 11.1
-- this
-- Identifier
-- Literal
-- ArrayLiteral
-- ObjectLiteral
-- ( Expression )
PrimaryExpression :: { AST.JSNode }
PrimaryExpression : 'this' { fp (AST.NT (AST.JSLiteral "this") (ss $1) (gc $1))}
| Identifier { $1 {- PrimaryExpression1 -}}
| Literal { $1 {- PrimaryExpression2 -}}
| ArrayLiteral { $1 {- PrimaryExpression3 -}}
| ObjectLiteral { $1 {- PrimaryExpression4 -}}
| LParen Expression RParen { fp (AST.NN (AST.JSExpressionParen $1 $2 $3)) }
-- Identifier :: See 7.6
-- IdentifierName but not ReservedWord
-- IdentifierName :: See 7.6
-- IdentifierStart
-- IdentifierName IdentifierPart
Identifier :: { AST.JSNode }
Identifier : 'ident' { (AST.NT (AST.JSIdentifier (token_literal $1)) (ss $1) (gc $1))}
| 'get' { (AST.NT (AST.JSIdentifier "get") (ss $1) (gc $1))}
| 'set' { (AST.NT (AST.JSIdentifier "set") (ss $1) (gc $1))}
-- TODO: make this include any reserved word too, including future ones
IdentifierName :: { AST.JSNode }
IdentifierName : Identifier {$1}
| 'break' { fp (AST.NT (AST.JSIdentifier "break") (ss $1) (gc $1))}
| 'case' { fp (AST.NT (AST.JSIdentifier "case") (ss $1) (gc $1))}
| 'catch' { fp (AST.NT (AST.JSIdentifier "catch") (ss $1) (gc $1))}
| 'const' { fp (AST.NT (AST.JSIdentifier "const") (ss $1) (gc $1))}
| 'continue' { fp (AST.NT (AST.JSIdentifier "continue") (ss $1) (gc $1))}
| 'debugger' { fp (AST.NT (AST.JSIdentifier "debugger") (ss $1) (gc $1))}
| 'default' { fp (AST.NT (AST.JSIdentifier "default") (ss $1) (gc $1))}
| 'delete' { fp (AST.NT (AST.JSIdentifier "delete") (ss $1) (gc $1))}
| 'do' { fp (AST.NT (AST.JSIdentifier "do") (ss $1) (gc $1))}
| 'else' { fp (AST.NT (AST.JSIdentifier "else") (ss $1) (gc $1))}
| 'enum' { fp (AST.NT (AST.JSIdentifier "enum") (ss $1) (gc $1))}
| 'false' { fp (AST.NT (AST.JSIdentifier "false") (ss $1) (gc $1))}
| 'finally' { fp (AST.NT (AST.JSIdentifier "finally") (ss $1) (gc $1))}
| 'for' { fp (AST.NT (AST.JSIdentifier "for") (ss $1) (gc $1))}
| 'function' { fp (AST.NT (AST.JSIdentifier "function") (ss $1) (gc $1))}
| 'get' { fp (AST.NT (AST.JSIdentifier "get") (ss $1) (gc $1))}
| 'if' { fp (AST.NT (AST.JSIdentifier "if") (ss $1) (gc $1))}
| 'in' { fp (AST.NT (AST.JSIdentifier "in") (ss $1) (gc $1))}
| 'instanceof' { fp (AST.NT (AST.JSIdentifier "instanceof") (ss $1) (gc $1))}
| 'new' { fp (AST.NT (AST.JSIdentifier "new") (ss $1) (gc $1))}
| 'null' { fp (AST.NT (AST.JSIdentifier "null") (ss $1) (gc $1))}
| 'return' { fp (AST.NT (AST.JSIdentifier "return") (ss $1) (gc $1))}
| 'set' { fp (AST.NT (AST.JSIdentifier "set") (ss $1) (gc $1))}
| 'switch' { fp (AST.NT (AST.JSIdentifier "switch") (ss $1) (gc $1))}
| 'this' { fp (AST.NT (AST.JSIdentifier "this") (ss $1) (gc $1))}
| 'throw' { fp (AST.NT (AST.JSIdentifier "throw") (ss $1) (gc $1))}
| 'true' { fp (AST.NT (AST.JSIdentifier "true") (ss $1) (gc $1))}
| 'try' { fp (AST.NT (AST.JSIdentifier "try") (ss $1) (gc $1))}
| 'typeof' { fp (AST.NT (AST.JSIdentifier "typeof") (ss $1) (gc $1))}
| 'var' { fp (AST.NT (AST.JSIdentifier "var") (ss $1) (gc $1))}
| 'void' { fp (AST.NT (AST.JSIdentifier "void") (ss $1) (gc $1))}
| 'while' { fp (AST.NT (AST.JSIdentifier "while") (ss $1) (gc $1))}
| 'with' { fp (AST.NT (AST.JSIdentifier "with") (ss $1) (gc $1))}
| 'future' { fp (AST.NT (AST.JSIdentifier (token_literal $1)) (ss $1) (gc $1))}
-- ArrayLiteral : See 11.1.4
-- [ Elisionopt ]
-- [ ElementList ]
-- [ ElementList , Elisionopt ]
ArrayLiteral :: { AST.JSNode }
ArrayLiteral : LSquare RSquare { fp (AST.NN (AST.JSArrayLiteral $1 [] $2))}
| LSquare Elision RSquare { fp (AST.NN (AST.JSArrayLiteral $1 $2 $3))}
| LSquare ElementList RSquare { fp (AST.NN (AST.JSArrayLiteral $1 $2 $3))}
| LSquare ElementList Comma Elision RSquare { fp (AST.NN (AST.JSArrayLiteral $1 ($2++[$3]++$4) $5))}
| LSquare ElementList Comma RSquare { fp (AST.NN (AST.JSArrayLiteral $1 ($2++[$3]) $4))}
-- ElementList : See 11.1.4
-- Elisionopt AssignmentExpression
-- ElementList , Elisionopt AssignmentExpression
ElementList :: { [AST.JSNode] }
ElementList : Elision AssignmentExpression { (($1)++($2)) {- ElementList -}}
| AssignmentExpression { $1 {- ElementList -}}
| ElementList Comma Elision AssignmentExpression { (($1)++[fp (AST.NN (AST.JSElision $2))]++($3)++($4)) {- ElementList -}}
| ElementList Comma AssignmentExpression { (($1)++[fp (AST.NN (AST.JSElision $2))]++($3)) {- ElementList -}}
-- Elision : See 11.1.4
-- ,
-- Elision ,
Elision :: { [AST.JSNode] }
Elision : Comma { [ fp (AST.NN (AST.JSElision $1))] }
| Elision Comma { ($1 ++ [fp (AST.NN (AST.JSElision $2))]) }
-- ObjectLiteral : See 11.1.5
-- { }
-- { PropertyNameAndValueList }
-- { PropertyNameAndValueList , }
ObjectLiteral :: { AST.JSNode }
ObjectLiteral : LBrace RBrace { fp (AST.NN (AST.JSObjectLiteral $1 [] $2) )}
| LBrace PropertyNameandValueList RBrace { fp (AST.NN (AST.JSObjectLiteral $1 $2 $3) )}
| LBrace PropertyNameandValueList Comma RBrace { fp (AST.NN (AST.JSObjectLiteral $1 ($2++[$3]) $4) )}
-- <Property Name and Value List> ::= <Property Name> ':' <Assignment Expression>
-- | <Property Name and Value List> ',' <Property Name> ':' <Assignment Expression>
-- Seems we can have function declarations in the value part too
-- PropertyNameAndValueList : See 11.1.5
-- PropertyAssignment
-- PropertyNameAndValueList , PropertyAssignment
PropertyNameandValueList :: { [ AST.JSNode ] }
PropertyNameandValueList : PropertyAssignment { [$1] {- PropertyNameandValueList1 -} }
| PropertyNameandValueList Comma PropertyAssignment { ($1++[$2]++[$3]) {- PropertyNameandValueList2 -} }
-- PropertyAssignment : See 11.1.5
-- PropertyName : AssignmentExpression
-- get PropertyName() { FunctionBody }
-- set PropertyName( PropertySetParameterList ) { FunctionBody }
-- TODO: not clear if get/set are keywords, or just used in a specific context. Puzzling.
PropertyAssignment :: { AST.JSNode }
PropertyAssignment : PropertyName Colon AssignmentExpression { fp (AST.NN (AST.JSPropertyNameandValue $1 $2 $3)) }
-- Should be "get" in next, but is not a Token
| 'get' PropertyName LParen RParen FunctionBody
{ fp (AST.NN (AST.JSPropertyAccessor (AST.NT (AST.JSLiteral "get") (ss $1) (gc $1)) $2 $3 [] $4 $5)) }
-- Should be "set" in next, but is not a Token
| 'set' PropertyName LParen PropertySetParameterList RParen FunctionBody
{ fp (AST.NN (AST.JSPropertyAccessor (AST.NT (AST.JSLiteral "set") (ss $1) (gc $1)) $2 $3 [$4] $5 $6)) }
-- PropertyName : See 11.1.5
-- IdentifierName
-- StringLiteral
-- NumericLiteral
PropertyName :: { AST.JSNode }
PropertyName : IdentifierName { $1 {- PropertyName1 -}}
| StringLiteral { $1 {- PropertyName2 -}}
| NumericLiteral { $1 {- PropertyName3 -}}
-- PropertySetParameterList : See 11.1.5
-- Identifier
PropertySetParameterList :: { AST.JSNode }
PropertySetParameterList : Identifier { $1 {- PropertySetParameterList -}}
-- MemberExpression : See 11.2
-- PrimaryExpression
-- FunctionExpression
-- MemberExpression [ Expression ]
-- MemberExpression . IdentifierName
-- new MemberExpression Arguments
MemberExpression :: { [AST.JSNode] }
MemberExpression : PrimaryExpression { [$1] {- MemberExpression -}}
| FunctionExpression { [$1] {- MemberExpression -}}
| MemberExpression LSquare Expression RSquare { [fp (AST.NN (AST.JSMemberSquare $1 $2 $3 $4))] }
| MemberExpression Dot IdentifierName { [fp (AST.NN (AST.JSMemberDot $1 $2 $3))] }
| 'new' MemberExpression Arguments { (((fp (AST.NT (AST.JSLiteral "new") (ss $1) (gc $1))):$2)++[$3])}
-- NewExpression : See 11.2
-- MemberExpression
-- new NewExpression
NewExpression :: { [AST.JSNode] }
NewExpression : MemberExpression { $1 {- NewExpression -}}
| 'new' NewExpression { (fp (AST.NT (AST.JSLiteral "new") (ss $1) (gc $1))):$2 }
-- CallExpression : See 11.2
-- MemberExpression Arguments
-- CallExpression Arguments
-- CallExpression [ Expression ]
-- CallExpression . IdentifierName
CallExpression :: { [AST.JSNode] }
CallExpression : MemberExpression Arguments { $1++[$2] {- CallExpression -} }
| CallExpression Arguments { ($1++[fp (AST.NN (AST.JSCallExpression "()" [] [$2] []))]) }
| CallExpression LSquare Expression RSquare { ($1++[fp (AST.NN (AST.JSCallExpression "[]" [$2] [$3] [$4]))]) }
| CallExpression Dot IdentifierName { ($1++[fp (AST.NN (AST.JSCallExpression "." [$2] [$3] []))]) }
-- Arguments : See 11.2
-- ()
-- ( ArgumentList )
Arguments :: { AST.JSNode }
Arguments : LParen RParen { fp (AST.NN (AST.JSArguments $1 [] $2)) }
| LParen ArgumentList RParen { fp (AST.NN (AST.JSArguments $1 $2 $3)) }
-- ArgumentList : See 11.2
-- AssignmentExpression
-- ArgumentList , AssignmentExpression
ArgumentList :: { [AST.JSNode] }
ArgumentList : AssignmentExpression { $1 {- ArgumentList -}}
| ArgumentList Comma AssignmentExpression { $1++[$2]++$3 {- ArgumentList2 -} }
-- LeftHandSideExpression : See 11.2
-- NewExpression
-- CallExpression
LeftHandSideExpression :: { [AST.JSNode] }
LeftHandSideExpression : NewExpression { $1 {- LeftHandSideExpression1 -}}
| CallExpression { $1 {- LeftHandSideExpression12 -}}
-- PostfixExpression : See 11.3
-- LeftHandSideExpression
-- [no LineTerminator here]
-- LeftHandSideExpression ++
-- [no LineTerminator here]
-- LeftHandSideExpression --
PostfixExpression :: { [AST.JSNode] }
PostfixExpression : LeftHandSideExpression { $1 {- PostfixExpression -} }
| PostfixExpression Increment {[fp (AST.NN (AST.JSExpressionPostfix "++" $1 $2))]}
| PostfixExpression Decrement {[fp (AST.NN (AST.JSExpressionPostfix "--" $1 $2))]}
-- UnaryExpression : See 11.4
-- PostfixExpression
-- delete UnaryExpression
-- void UnaryExpression
-- typeof UnaryExpression
-- ++ UnaryExpression
-- -- UnaryExpression
-- + UnaryExpression
-- - UnaryExpression
-- ~ UnaryExpression
-- ! UnaryExpression
UnaryExpression :: { [AST.JSNode] }
UnaryExpression : PostfixExpression { $1 {- UnaryExpression -} }
| Delete UnaryExpression { ((fp (AST.NN (AST.JSUnary "delete " $1))):$2)}
| Void UnaryExpression { ((fp (AST.NN (AST.JSUnary "void " $1))):$2)}
| Typeof UnaryExpression { ((fp (AST.NN (AST.JSUnary "typeof " $1))):$2)}
| Increment UnaryExpression { ((fp (AST.NN (AST.JSUnary "++" $1))):$2) }
| Decrement UnaryExpression { ((fp (AST.NN (AST.JSUnary "--" $1))):$2)}
| Plus UnaryExpression { ((fp (AST.NN (AST.JSUnary "+" $1))):$2)}
| Minus UnaryExpression { ((fp (AST.NN (AST.JSUnary "-" $1))):$2)}
| Tilde UnaryExpression { ((fp (AST.NN (AST.JSUnary "~" $1))):$2)}
| Not UnaryExpression { ((fp (AST.NN (AST.JSUnary "!" $1))):$2)}
-- MultiplicativeExpression : See 11.5
-- UnaryExpression
-- MultiplicativeExpression * UnaryExpression
-- MultiplicativeExpression / UnaryExpression
-- MultiplicativeExpression % UnaryExpression
MultiplicativeExpression :: { [AST.JSNode] }
MultiplicativeExpression : UnaryExpression { $1 {- MultiplicativeExpression -}}
| MultiplicativeExpression Mul UnaryExpression { [fp (AST.NN (AST.JSExpressionBinary "*" $1 $2 $3))]}
| MultiplicativeExpression Div UnaryExpression { [fp (AST.NN (AST.JSExpressionBinary "/" $1 $2 $3))]}
| MultiplicativeExpression Mod UnaryExpression { [fp (AST.NN (AST.JSExpressionBinary "%" $1 $2 $3))]}
-- AdditiveExpression : See 11.6
-- MultiplicativeExpression
-- AdditiveExpression + MultiplicativeExpression
-- AdditiveExpression - MultiplicativeExpression
AdditiveExpression :: { [AST.JSNode] }
AdditiveExpression : AdditiveExpression Plus MultiplicativeExpression { [fp (AST.NN (AST.JSExpressionBinary "+" $1 $2 $3))]}
| AdditiveExpression Minus MultiplicativeExpression { [fp (AST.NN (AST.JSExpressionBinary "-" $1 $2 $3))]}
| MultiplicativeExpression { $1 {- (goRegExp $1)-} {- AdditiveExpression -} }
-- ShiftExpression : See 11.7
-- AdditiveExpression
-- ShiftExpression << AdditiveExpression
-- ShiftExpression >> AdditiveExpression
-- ShiftExpression >>> AdditiveExpression
ShiftExpression :: { [AST.JSNode] }
ShiftExpression : ShiftExpression Lsh AdditiveExpression { [fp (AST.NN (AST.JSExpressionBinary "<<" $1 $2 $3))]}
| ShiftExpression Rsh AdditiveExpression { [fp (AST.NN (AST.JSExpressionBinary ">>" $1 $2 $3))]}
| ShiftExpression Ursh AdditiveExpression { [fp (AST.NN (AST.JSExpressionBinary ">>>" $1 $2 $3))]}
| AdditiveExpression { $1 {- ShiftExpression -}}
-- RelationalExpression : See 11.8
-- ShiftExpression
-- RelationalExpression < ShiftExpression
-- RelationalExpression > ShiftExpression
-- RelationalExpression <= ShiftExpression
-- RelationalExpression >= ShiftExpression
-- RelationalExpression instanceof ShiftExpression
-- RelationalExpression in ShiftExpression
RelationalExpression :: { [AST.JSNode] }
RelationalExpression : ShiftExpression { $1 {- RelationalExpression -}}
| RelationalExpression Lt ShiftExpression { [fp (AST.NN (AST.JSExpressionBinary "<" $1 $2 $3))]}
| RelationalExpression Gt ShiftExpression { [fp (AST.NN (AST.JSExpressionBinary ">" $1 $2 $3))]}
| RelationalExpression Le ShiftExpression { [fp (AST.NN (AST.JSExpressionBinary "<=" $1 $2 $3))]}
| RelationalExpression Ge ShiftExpression { [fp (AST.NN (AST.JSExpressionBinary ">=" $1 $2 $3))]}
| RelationalExpression Instanceof ShiftExpression { [fp (AST.NN (AST.JSExpressionBinary " instanceof " $1 $2 $3))]}
| RelationalExpression In ShiftExpression { [fp (AST.NN (AST.JSExpressionBinary " in " $1 $2 $3))]}
-- RelationalExpressionNoIn : See 11.8
-- ShiftExpression
-- RelationalExpressionNoIn < ShiftExpression
-- RelationalExpressionNoIn > ShiftExpression
-- RelationalExpressionNoIn <= ShiftExpression
-- RelationalExpressionNoIn >= ShiftExpression
-- RelationalExpressionNoIn instanceof ShiftExpression
RelationalExpressionNoIn :: { [AST.JSNode] }
RelationalExpressionNoIn : ShiftExpression { $1 {- RelationalExpressionNoIn -}}
| RelationalExpressionNoIn Lt ShiftExpression { [fp (AST.NN (AST.JSExpressionBinary "<" $1 $2 $3))]}
| RelationalExpressionNoIn Gt ShiftExpression { [fp (AST.NN (AST.JSExpressionBinary ">" $1 $2 $3))]}
| RelationalExpressionNoIn Le ShiftExpression { [fp (AST.NN (AST.JSExpressionBinary "<=" $1 $2 $3))]}
| RelationalExpressionNoIn Ge ShiftExpression { [fp (AST.NN (AST.JSExpressionBinary ">=" $1 $2 $3))]}
| RelationalExpressionNoIn Instanceof ShiftExpression { [fp (AST.NN (AST.JSExpressionBinary " instanceof " $1 $2 $3))]}
-- EqualityExpression : See 11.9
-- RelationalExpression
-- EqualityExpression == RelationalExpression
-- EqualityExpression != RelationalExpression
-- EqualityExpression === RelationalExpression
-- EqualityExpression !== RelationalExpression
EqualityExpression :: { [AST.JSNode] }
EqualityExpression : RelationalExpression { $1 {- EqualityExpression -} }
| EqualityExpression Equal RelationalExpression { [fp (AST.NN (AST.JSExpressionBinary "==" $1 $2 $3))]}
| EqualityExpression Ne RelationalExpression { [fp (AST.NN (AST.JSExpressionBinary "!=" $1 $2 $3))]}
| EqualityExpression StrictEq RelationalExpression { [fp (AST.NN (AST.JSExpressionBinary "===" $1 $2 $3))]}
| EqualityExpression StrictNe RelationalExpression { [fp (AST.NN (AST.JSExpressionBinary "!==" $1 $2 $3))]}
-- EqualityExpressionNoIn : See 11.9
-- RelationalExpressionNoIn
-- EqualityExpressionNoIn == RelationalExpressionNoIn
-- EqualityExpressionNoIn != RelationalExpressionNoIn
-- EqualityExpressionNoIn === RelationalExpressionNoIn
-- EqualityExpressionNoIn !== RelationalExpressionNoIn
EqualityExpressionNoIn :: { [AST.JSNode] }
EqualityExpressionNoIn : RelationalExpressionNoIn { $1 {- EqualityExpressionNoIn -} }
| EqualityExpressionNoIn Equal RelationalExpression { [fp (AST.NN (AST.JSExpressionBinary "==" $1 $2 $3))]}
| EqualityExpressionNoIn Ne RelationalExpression { [fp (AST.NN (AST.JSExpressionBinary "!=" $1 $2 $3))]}
| EqualityExpressionNoIn StrictEq RelationalExpression { [fp (AST.NN (AST.JSExpressionBinary "===" $1 $2 $3))]}
| EqualityExpressionNoIn StrictNe RelationalExpression { [fp (AST.NN (AST.JSExpressionBinary "!==" $1 $2 $3))]}
-- BitwiseANDExpression : See 11.10
-- EqualityExpression
-- BitwiseANDExpression & EqualityExpression
BitwiseAndExpression :: { [AST.JSNode] }
BitwiseAndExpression : EqualityExpression { $1 {- BitwiseAndExpression -} }
| BitwiseAndExpression BitAnd EqualityExpression { [fp (AST.NN (AST.JSExpressionBinary "&" $1 $2 $3))]}
-- BitwiseANDExpressionNoIn : See 11.10
-- EqualityExpressionNoIn
-- BitwiseANDExpressionNoIn & EqualityExpressionNoIn
BitwiseAndExpressionNoIn :: { [AST.JSNode] }
BitwiseAndExpressionNoIn : EqualityExpressionNoIn { $1 {- BitwiseAndExpression -} }
| BitwiseAndExpressionNoIn BitAnd EqualityExpressionNoIn { [fp (AST.NN (AST.JSExpressionBinary "&" $1 $2 $3))]}
-- BitwiseXORExpression : See 11.10
-- BitwiseANDExpression
-- BitwiseXORExpression ^ BitwiseANDExpression
BitwiseXOrExpression :: { [AST.JSNode] }
BitwiseXOrExpression : BitwiseAndExpression { $1 {- BitwiseXOrExpression -} }
| BitwiseXOrExpression BitXor BitwiseAndExpression { [fp (AST.NN (AST.JSExpressionBinary "^" $1 $2 $3))]}
-- BitwiseXORExpressionNoIn : See 11.10
-- BitwiseANDExpressionNoIn
-- BitwiseXORExpressionNoIn ^ BitwiseANDExpressionNoIn
BitwiseXOrExpressionNoIn :: { [AST.JSNode] }
BitwiseXOrExpressionNoIn : BitwiseAndExpressionNoIn { $1 {- BitwiseXOrExpression -} }
| BitwiseXOrExpressionNoIn BitXor BitwiseAndExpressionNoIn { [fp (AST.NN (AST.JSExpressionBinary "^" $1 $2 $3))]}
-- BitwiseORExpression : See 11.10
-- BitwiseXORExpression
-- BitwiseORExpression | BitwiseXORExpression
BitwiseOrExpression :: { [AST.JSNode] }
BitwiseOrExpression : BitwiseXOrExpression { $1 {- BitwiseOrExpression -} }
| BitwiseOrExpression BitOr BitwiseXOrExpression { [fp (AST.NN (AST.JSExpressionBinary "|" $1 $2 $3))]}
-- BitwiseORExpressionNoIn : See 11.10
-- BitwiseXORExpressionNoIn
-- BitwiseORExpressionNoIn | BitwiseXORExpressionNoIn
BitwiseOrExpressionNoIn :: { [AST.JSNode] }
BitwiseOrExpressionNoIn : BitwiseXOrExpressionNoIn { $1 {- BitwiseOrExpression -} }
| BitwiseOrExpressionNoIn BitOr BitwiseXOrExpressionNoIn { [fp (AST.NN (AST.JSExpressionBinary "|" $1 $2 $3))]}
-- LogicalANDExpression : See 11.11
-- BitwiseORExpression
-- LogicalANDExpression && BitwiseORExpression
LogicalAndExpression :: { [AST.JSNode] }
LogicalAndExpression : BitwiseOrExpression { $1 {- LogicalAndExpression -} }
| LogicalAndExpression And BitwiseOrExpression { [fp (AST.NN (AST.JSExpressionBinary "&&" $1 $2 $3))]}
-- LogicalANDExpressionNoIn : See 11.11
-- BitwiseORExpressionNoIn
-- LogicalANDExpressionNoIn && BitwiseORExpressionNoIn
LogicalAndExpressionNoIn :: { [AST.JSNode] }
LogicalAndExpressionNoIn : BitwiseOrExpressionNoIn { $1 {- LogicalAndExpression -} }
| LogicalAndExpressionNoIn And BitwiseOrExpressionNoIn { [fp (AST.NN (AST.JSExpressionBinary "&&" $1 $2 $3))]}
-- LogicalORExpression : See 11.11
-- LogicalANDExpression
-- LogicalORExpression || LogicalANDExpression
LogicalOrExpression :: { [AST.JSNode] }
LogicalOrExpression : LogicalAndExpression { $1 {- LogicalOrExpression -} }
| LogicalOrExpression Or LogicalAndExpression { [fp (AST.NN (AST.JSExpressionBinary "||" $1 $2 $3))]}
-- LogicalORExpressionNoIn : See 11.11
-- LogicalANDExpressionNoIn
-- LogicalORExpressionNoIn || LogicalANDExpressionNoIn
LogicalOrExpressionNoIn :: { [AST.JSNode] }
LogicalOrExpressionNoIn : LogicalAndExpressionNoIn { $1 {- LogicalOrExpression -} }
| LogicalOrExpressionNoIn Or LogicalAndExpressionNoIn { [fp (AST.NN (AST.JSExpressionBinary "||" $1 $2 $3))]}
-- ConditionalExpression : See 11.12
-- LogicalORExpression
-- LogicalORExpression ? AssignmentExpression : AssignmentExpression
ConditionalExpression :: { [AST.JSNode] }
ConditionalExpression : LogicalOrExpression { $1 {- ConditionalExpression -} }
| LogicalOrExpression Hook AssignmentExpression Colon AssignmentExpression
{ [fp (AST.NN (AST.JSExpressionTernary $1 $2 $3 $4 $5))] }
-- ConditionalExpressionNoIn : See 11.12
-- LogicalORExpressionNoIn
-- LogicalORExpressionNoIn ? AssignmentExpressionNoIn : AssignmentExpressionNoIn
ConditionalExpressionNoIn :: { [AST.JSNode] }
ConditionalExpressionNoIn : LogicalOrExpressionNoIn { $1 {- ConditionalExpression -} }
| LogicalOrExpressionNoIn Hook AssignmentExpressionNoIn Colon AssignmentExpressionNoIn
{ [fp (AST.NN (AST.JSExpressionTernary $1 $2 $3 $4 $5))] }
-- AssignmentExpression : See 11.13
-- ConditionalExpression
-- LeftHandSideExpression AssignmentOperator AssignmentExpression
AssignmentExpression :: { [AST.JSNode] }
AssignmentExpression : ConditionalExpression { $1 {- AssignmentExpression -}}
| LeftHandSideExpression AssignmentOperator AssignmentExpression
{ ($1++[$2]++$3) }
-- AssignmentExpressionNoIn : See 11.13
-- ConditionalExpressionNoIn
-- LeftHandSideExpression AssignmentOperator AssignmentExpressionNoIn
AssignmentExpressionNoIn :: { [AST.JSNode] }
AssignmentExpressionNoIn : ConditionalExpressionNoIn { $1 {- AssignmentExpression -}}
| LeftHandSideExpression AssignmentOperator AssignmentExpressionNoIn
{ ($1++[$2]++$3) }
-- AssignmentOperator : one of See 11.13
-- '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '>>>=' | '&=' | '^=' | '|='
AssignmentOperator :: { AST.JSNode }
AssignmentOperator : Assign { fp (AST.NN (AST.JSOperator $1))}
| SimpleAssign { fp (AST.NN (AST.JSOperator $1))}
-- Expression : See 11.14
-- AssignmentExpression
-- Expression , AssignmentExpression
Expression :: { AST.JSNode }
Expression : AssignmentExpression { fp (AST.NN (AST.JSExpression $1)) {- Expression -} }
| Expression Comma AssignmentExpression { fp (AST.NN (AST.JSExpression ($1:[$2]++$3))) {- Expression2 -} }
-- ExpressionNoIn : See 11.14
-- AssignmentExpressionNoIn
-- ExpressionNoIn , AssignmentExpressionNoIn
ExpressionNoIn :: { AST.JSNode }
ExpressionNoIn : AssignmentExpressionNoIn { fp (AST.NN (AST.JSExpression $1)) {- ExpressionNoIn -} }
| ExpressionNoIn Comma AssignmentExpressionNoIn { fp (AST.NN (AST.JSExpression ($1:[$2]++$3))) {- ExpressionNoIn2 -} }
-- TODO: still required?
ExpressionOpt :: { [AST.JSNode] }
ExpressionOpt : Expression { [$1] {- ExpressionOpt -}}
| { [] {- ExpressionOpt -}}
ExpressionNoInOpt :: { [AST.JSNode] }
ExpressionNoInOpt : ExpressionNoIn { [$1] {- ExpressionOpt -}}
| { [] {- ExpressionOpt -}}
-- Statement : See clause 12
-- Block
-- VariableStatement
-- EmptyStatement
-- ExpressionStatement
-- IfStatement
-- IterationStatement
-- ContinueStatement
-- BreakStatement
-- ReturnStatement
-- WithStatement
-- LabelledStatement
-- SwitchStatement
-- ThrowStatement
-- TryStatement
-- DebuggerStatement
Statement :: { AST.JSNode }
Statement : StatementNoEmpty { $1 {- Statement1 -}}
| EmptyStatement { $1 {- Statement3 -}}
StatementNoEmpty :: { AST.JSNode }
StatementNoEmpty : StatementBlock { $1 {- StatementNoEmpty1 -}}
| VariableStatement { $1 {- StatementNoEmpty2 -}}
| ExpressionStatement { $1 {- StatementNoEmpty4 -}}
| IfStatement { $1 {- StatementNoEmpty5 -}}
| IterationStatement { $1 {- StatementNoEmpty6 -}}
| ContinueStatement { $1 {- StatementNoEmpty7 -}}
| BreakStatement { $1 {- StatementNoEmpty8 -}}
| ReturnStatement { $1 {- StatementNoEmpty9 -}}
| WithStatement { $1 {- StatementNoEmpty10 -}}
| LabelledStatement { $1 {- StatementNoEmpty11 -}}
| SwitchStatement { $1 {- StatementNoEmpty12 -}}
| ThrowStatement { $1 {- StatementNoEmpty13 -}}
| TryStatement { $1 {- StatementNoEmpty14 -}}
| DebuggerStatement { $1 {- StatementNoEmpty15 -}}
StatementBlock :: { AST.JSNode }
StatementBlock : LBrace RBrace { fp (AST.NN (AST.JSBlock [$1] [] [$2])) }
| LBrace StatementList RBrace { fp (AST.NN (AST.JSBlock [$1] $2 [$3])) }
-- Block : See 12.1
-- { StatementListopt }
Block :: { AST.JSNode }
Block : LBrace RBrace { fp (AST.NN (AST.JSBlock [$1] [] [$2])) }
| LBrace StatementList RBrace { fp (AST.NN (AST.JSBlock [$1] $2 [$3])) }
-- StatementList : See 12.1
-- Statement
-- StatementList Statement
StatementList :: { [AST.JSNode] }
StatementList : Statement { [$1] {- StatementList1 -} }
| StatementList Statement { ($1++[$2]) {- StatementList2 -} }
-- VariableStatement : See 12.2
-- var VariableDeclarationList ;
VariableStatement :: { AST.JSNode }
VariableStatement : Var VariableDeclarationList AutoSemi { fp (AST.NN (AST.JSVariables $1 $2 $3))}
| Const VariableDeclarationList AutoSemi { fp (AST.NN (AST.JSVariables $1 $2 $3))}
-- VariableDeclarationList : See 12.2
-- VariableDeclaration
-- VariableDeclarationList , VariableDeclaration
VariableDeclarationList :: { [AST.JSNode] }
VariableDeclarationList : VariableDeclaration { [$1] {- VariableDeclarationList -}}
| VariableDeclarationList Comma VariableDeclaration { ($1++[$2]++[$3]) {- VariableDeclarationList -}}
-- VariableDeclarationListNoIn : See 12.2
-- VariableDeclarationNoIn
-- VariableDeclarationListNoIn , VariableDeclarationNoIn
VariableDeclarationListNoIn :: { [AST.JSNode] }
VariableDeclarationListNoIn : VariableDeclarationNoIn { [$1] {- VariableDeclarationList -}}
| VariableDeclarationListNoIn Comma VariableDeclarationNoIn { ($1++[$2]++[$3]) {- VariableDeclarationListNoIn -}}
-- VariableDeclaration : See 12.2
-- Identifier Initialiseropt
VariableDeclaration :: { AST.JSNode }
VariableDeclaration : Identifier { fp (AST.NN (AST.JSVarDecl $1 []))}
| Identifier Initializer { fp (AST.NN (AST.JSVarDecl $1 $2))}
-- VariableDeclarationNoIn : See 12.2
-- Identifier InitialiserNoInopt
VariableDeclarationNoIn :: { AST.JSNode }
VariableDeclarationNoIn : Identifier InitializerNoIn { fp (AST.NN (AST.JSVarDecl $1 $2)) }
| Identifier { fp (AST.NN (AST.JSVarDecl $1 [])) }
-- Initialiser : See 12.2
-- = AssignmentExpression
Initializer :: { [AST.JSNode] }
Initializer : SimpleAssign AssignmentExpression { $1:$2 {- Initializer -} }
-- InitialiserNoIn : See 12.2
-- = AssignmentExpressionNoIn
InitializerNoIn :: { [AST.JSNode] }
InitializerNoIn : SimpleAssign AssignmentExpressionNoIn { $1:$2 {- InitializerNoIn -}}
-- EmptyStatement : See 12.3
-- ;
EmptyStatement :: { AST.JSNode }
EmptyStatement : Semi { $1 }
-- ExpressionStatement : See 12.4
-- [lookahead not in {{, function}] Expression ;
-- TODO: Sort out lookahead issue. Maybe by just putting production lower to set reduce/reduce conflict
-- According to http://sideshowbarker.github.com/es5-spec/#x12.4, the ambiguity is with
-- Block or FunctionDeclaration
ExpressionStatement :: { AST.JSNode }
ExpressionStatement : Expression { $1 {- ExpressionStatement -} }
-- IfStatement : See 12.5
-- if ( Expression ) Statement else Statement
-- if ( Expression ) Statement
IfStatement :: { AST.JSNode } -- +++XXXX++
IfStatement : If LParen Expression RParen StatementSemi IfElseRest
{ (fp (AST.NN (AST.JSIf $1 $2 $3 $4 $5 $6)) ) }
IfElseRest :: { [AST.JSNode] }
IfElseRest : Else Statement { [$1,$2] }
| { [] }
StatementSemi :: { [AST.JSNode] }
StatementSemi : StatementNoEmpty Semi { [$1,$2] {- StatementSemi1 -}}
| StatementNoEmpty { [$1] {- StatementSemi2 -}}
| Semi { [$1] {- StatementSemi3 -}}
-- IterationStatement : See 12.6
-- do Statement while ( Expression );
-- while ( Expression ) Statement
-- for (ExpressionNoInopt; Expressionopt ; Expressionopt ) Statement
-- for ( var VariableDeclarationListNoIn; Expressionopt ; Expressionopt ) Statement
-- for ( LeftHandSideExpression in Expression ) Statement
-- for ( var VariableDeclarationNoIn in Expression ) Statement
IterationStatement :: { AST.JSNode }
IterationStatement : Do Statement While LParen Expression RParen AutoSemi
{ fp (AST.NN (AST.JSDoWhile $1 $2 $3 $4 $5 $6 $7)) }
| While LParen Expression RParen Statement
{ fp (AST.NN (AST.JSWhile $1 $2 $3 $4 $5)) }
| For LParen ExpressionNoInOpt Semi ExpressionOpt Semi ExpressionOpt RParen Statement
{ fp (AST.NN (AST.JSFor $1 $2 $3 $4 $5 $6 $7 $8 $9)) }
| For LParen Var VariableDeclarationListNoIn Semi ExpressionOpt Semi ExpressionOpt RParen Statement
{ fp (AST.NN (AST.JSForVar $1 $2 $3 $4 $5 $6 $7 $8 $9 $10)) }
| For LParen LeftHandSideExpression In Expression RParen Statement
{ fp (AST.NN (AST.JSForIn $1 $2 $3 $4 $5 $6 $7)) }
| For LParen Var VariableDeclarationNoIn In Expression RParen Statement
{ fp (AST.NN (AST.JSForVarIn $1 $2 $3 $4 $5 $6 $7 $8)) }
-- ContinueStatement : See 12.7
-- continue [no LineTerminator here] Identifieropt ;
-- TODO: deal with [no LineTerminator here]
ContinueStatement :: { AST.JSNode }
ContinueStatement : Continue AutoSemi { fp (AST.NN (AST.JSContinue $1 [] $2)) }
| Continue Identifier AutoSemi { fp (AST.NN (AST.JSContinue $1 [$2] $3)) }
-- BreakStatement : See 12.8
-- break [no LineTerminator here] Identifieropt ;
-- TODO: deal with [no LineTerminator here]
BreakStatement :: { AST.JSNode }
BreakStatement : Break AutoSemi { fp (AST.NN (AST.JSBreak $1 [] $2)) }
| Break Identifier AutoSemi { fp (AST.NN (AST.JSBreak $1 [$2] $3)) }
-- ReturnStatement : See 12.9
-- return [no LineTerminator here] Expressionopt ;
-- TODO: deal with [no LineTerminator here]
ReturnStatement :: { AST.JSNode }
ReturnStatement : Return AutoSemi { fp (AST.NN (AST.JSReturn $1 [] $2)) }
| Return Expression AutoSemi { fp (AST.NN (AST.JSReturn $1 [$2] $3)) }
-- WithStatement : See 12.10
-- with ( Expression ) Statement
WithStatement :: { AST.JSNode }
WithStatement : With LParen Expression RParen Statement AutoSemi { fp (AST.NN (AST.JSWith $1 $2 $3 $4 [$5,$6])) }
-- SwitchStatement : See 12.11
-- switch ( Expression ) CaseBlock
SwitchStatement :: { AST.JSNode }
SwitchStatement : Switch LParen Expression RParen CaseBlock { (AST.NN (AST.JSSwitch $1 $2 $3 $4 $5)) }
-- CaseBlock : See 12.11
-- { CaseClausesopt }
-- { CaseClausesopt DefaultClause CaseClausesopt }
CaseBlock :: { AST.JSNode }
CaseBlock : LBrace CaseClausesOpt RBrace { fp (AST.NN (AST.JSBlock [$1] $2 [$3])){- CaseBlock1 -}}
| LBrace CaseClausesOpt DefaultClause CaseClausesOpt RBrace { fp (AST.NN (AST.JSBlock [$1] ($2++[$3]++$4) [$5])){- CaseBlock2 -}}
-- CaseClauses : See 12.11
-- CaseClause
-- CaseClauses CaseClause
CaseClausesOpt :: { [AST.JSNode] }
CaseClausesOpt : CaseClause { [$1] {- CaseClauses1 -}}
| CaseClausesOpt CaseClause { ($1++[$2]) {- CaseClauses2 -}}
| { [fp (AST.NT (AST.JSLiteral "") tokenPosnEmpty []) ] } -- { [] }
-- CaseClause : See 12.11
-- case Expression : StatementListopt
CaseClause :: { AST.JSNode }
CaseClause : Case Expression Colon StatementList { fp (AST.NN (AST.JSCase $1 $2 $3 $4)) }
| Case Expression Colon { fp (AST.NN (AST.JSCase $1 $2 $3 [])) }
-- DefaultClause : See 12.11
-- default : StatementListopt
DefaultClause :: { AST.JSNode }
DefaultClause : Default Colon { fp (AST.NN (AST.JSDefault $1 $2 [])) }
| Default Colon StatementList { fp (AST.NN (AST.JSDefault $1 $2 $3)) }
-- LabelledStatement : See 12.12
-- Identifier : Statement
LabelledStatement :: { AST.JSNode }
LabelledStatement : Identifier Colon Statement { fp (AST.NN (AST.JSLabelled $1 $2 $3)) }
-- ThrowStatement : See 12.13
-- throw [no LineTerminator here] Expression ;
-- TODO : sort out no LineTerminator here
-- Does it need a semi at the end?
ThrowStatement :: { AST.JSNode }
ThrowStatement : Throw Expression { fp (AST.NN (AST.JSThrow $1 $2)) }
-- Note: worked in updated syntax as per https://developer.mozilla.org/en/JavaScript/Reference/Statements/try...catch
-- i.e., 0 or more catches, then an optional finally
-- TryStatement : See 12.14
-- try Block Catch
-- try Block Finally
-- try Block Catch Finally
TryStatement :: { AST.JSNode }
TryStatement : Try Block Catches { fp (AST.NN (AST.JSTry $1 $2 $3) ) {- TryStatement1 -} }
| Try Block Finally { fp (AST.NN (AST.JSTry $1 $2 [$3]) ) {- TryStatement2 -} }
| Try Block Catches Finally { fp (AST.NN (AST.JSTry $1 $2 ($3++[$4])) ) {- TryStatement3 -} }
Catches :: { [AST.JSNode] }
Catches : Catch { [$1] {- Catches 1 -} }
| Catches Catch { ($1++[$2]) {- Catches 2 -} }
-- Note: worked in updated syntax as per https://developer.mozilla.org/en/JavaScript/Reference/Statements/try...catch
-- <Catch> ::= 'catch' '(' Identifier ')' <Block>
-- becomes
-- <Catch> ::= 'catch' '(' Identifier ')' <Block>
-- | 'catch' '(' Identifier 'if' ConditionalExpression ')' <Block>
Catch :: { AST.JSNode }
Catch : CatchL LParen Identifier RParen Block { fp (AST.NN (AST.JSCatch $1 $2 $3 [ ] $4 $5)) }
| CatchL LParen Identifier If ConditionalExpression RParen Block { fp (AST.NN (AST.JSCatch $1 $2 $3 ($4:$5) $6 $7)) }
-- Finally : See 12.14
-- finally Block
Finally :: { AST.JSNode }
Finally : FinallyL Block { fp (AST.NN (AST.JSFinally $1 $2)) }
-- DebuggerStatement : See 12.15
-- debugger ;
DebuggerStatement :: { AST.JSNode }
DebuggerStatement : 'debugger' AutoSemi { fp (AST.NT (AST.JSLiteral "debugger") (ss $1) (gc $1)) }
-- FunctionDeclaration : See clause 13
-- function Identifier ( FormalParameterListopt ) { FunctionBody }
FunctionDeclaration :: { AST.JSNode }
FunctionDeclaration : Function Identifier LParen FormalParameterList RParen FunctionBody
{ fp (AST.NN (AST.JSFunction $1 $2 $3 $4 $5 $6) ) }
| Function Identifier LParen RParen FunctionBody
{ fp (AST.NN (AST.JSFunction $1 $2 $3 [] $4 $5) ) }
-- FunctionExpression : See clause 13
-- function Identifieropt ( FormalParameterListopt ) { FunctionBody }
FunctionExpression :: { AST.JSNode }
FunctionExpression : Function IdentifierOpt LParen RParen FunctionBody
{ fp (AST.NN (AST.JSFunctionExpression $1 $2 $3 [] $4 $5) ) }
| Function IdentifierOpt LParen FormalParameterList RParen FunctionBody
{ fp (AST.NN (AST.JSFunctionExpression $1 $2 $3 $4 $5 $6) ) }
IdentifierOpt :: { [AST.JSNode] }
IdentifierOpt : Identifier { [$1] {- IdentifierOpt -}}
| { [] {- IdentifierOpt -}}
-- FormalParameterList : See clause 13
-- Identifier
-- FormalParameterList , Identifier
FormalParameterList :: { [AST.JSNode] }
FormalParameterList : Identifier { [$1] {- FormalParameterList -}}
| FormalParameterList Comma Identifier { ($1++[$2]++[$3]) }
-- FunctionBody : See clause 13
-- SourceElementsopt
FunctionBody :: { AST.JSNode }
FunctionBody : LBrace SourceElements RBrace { (AST.NN (AST.JSBlock [$1] $2 [$3]) ) }
| LBrace RBrace { (AST.NN (AST.JSBlock [$1] [] [$2]) ) }
-- Program : See clause 14
-- SourceElementsopt
Program :: { AST.JSNode }
Program : SourceElementsTop Eof { (combineTop $1 $2) {- Program -}}
| Eof { fp (AST.NN (AST.JSSourceElementsTop [$1])) }
-- For debugging/other entry points
LiteralMain :: { AST.JSNode }
LiteralMain : Literal Eof { $1 }
PrimaryExpressionMain :: { AST.JSNode }
PrimaryExpressionMain : PrimaryExpression Eof { $1 }
StatementMain :: { AST.JSNode }
StatementMain : Statement Eof { $1 }
-- SourceElements : See clause 14
-- SourceElement
-- SourceElements SourceElement
SourceElements :: { [AST.JSNode] }
SourceElements : SourceElement { [$1] {- SourceElements -} }
| SourceElements SourceElement { $1++[$2] {- SourceElements -} }
SourceElementsTop :: { AST.JSNode }
SourceElementsTop : SourceElement { fp (AST.NN (AST.JSSourceElementsTop [$1]) ) }
| SourceElementsTop SourceElement { (combineSourceElementsTop $1 $2) }
-- SourceElement :
-- Statement
-- FunctionDeclaration
SourceElement :: { AST.JSNode }
SourceElement : Statement { $1 {- SourceElement1 -} }
| FunctionDeclaration { $1 {- SourceElement2 -} }
{
combineSourceElementsTop :: AST.JSNode -> AST.JSNode -> AST.JSNode
combineSourceElementsTop (AST.NN (AST.JSSourceElementsTop xs)) x1 = fp (AST.NN (AST.JSSourceElementsTop (xs++[x1])))
combineTop :: AST.JSNode -> AST.JSNode -> AST.JSNode
combineTop (AST.NN (AST.JSSourceElementsTop xs)) x1 = fp (AST.NN (AST.JSSourceElementsTop (xs++[x1])))
parseError :: Token -> Alex a
-- parseError = throwError . UnexpectedToken
parseError tok = alexError (show tok)
-- --------------------------------
{-
mex :: [AST.JSNode] -> TokenPosn
mex [] = tokenPosnEmpty
mex xs = ex (head xs)
ex :: AST.JSNode -> TokenPosn
ex (AST.NN _node span _c) = span
-}
--ss token = toSrcSpan (token_span token)
ss :: Token -> TokenPosn
ss token = token_span token
-- ------------------------------
gc :: Token -> [CommentAnnotation]
gc token = token_comment token
mgc :: [Token] -> [CommentAnnotation]
mgc xs = concatMap gc xs
-- ---------------------------------------------------------------------
fp :: AST.JSNode -> AST.JSNode
fp (AST.NN x) = (AST.NN x)
fp (AST.NT x p cs) = (AST.NT x p cs)
{-
fp (AST.NN x p cs) = (AST.NN x p' cs)
where
p' = case (filter (/= NoComment) cs) of
[] -> p
[(CommentA posn _)] -> posn
((CommentA posn _):_) -> posn
-}
}
-- Set emacs mode
-- Local Variables:
-- mode:haskell
-- End:
Jump to Line
Something went wrong with that request. Please try again.