123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- ;;; ECMAScript for Guile
- ;; Copyright (C) 2009, 2010 Free Software Foundation, Inc.
- ;;;; This library is free software; you can redistribute it and/or
- ;;;; modify it under the terms of the GNU Lesser General Public
- ;;;; License as published by the Free Software Foundation; either
- ;;;; version 3 of the License, or (at your option) any later version.
- ;;;;
- ;;;; This library is distributed in the hope that it will be useful,
- ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- ;;;; Lesser General Public License for more details.
- ;;;;
- ;;;; You should have received a copy of the GNU Lesser General Public
- ;;;; License along with this library; if not, write to the Free Software
- ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- ;;; Code:
- (define-module (language ecmascript parse)
- #:use-module (system base lalr)
- #:use-module (language ecmascript tokenize)
- #:export (read-ecmascript read-ecmascript/1 make-parser))
- (define* (syntax-error message #:optional token)
- (if (lexical-token? token)
- (throw 'syntax-error #f message
- (and=> (lexical-token-source token)
- source-location->source-properties)
- (or (lexical-token-value token)
- (lexical-token-category token))
- #f)
- (throw 'syntax-error #f message #f token #f)))
- (define (read-ecmascript port)
- (let ((parse (make-parser)))
- (parse (make-tokenizer port) syntax-error)))
- (define (read-ecmascript/1 port)
- (let ((parse (make-parser)))
- (parse (make-tokenizer/1 port) syntax-error)))
- (define *eof-object*
- (call-with-input-string "" read-char))
- (define (make-parser)
- ;; Return a fresh ECMAScript parser. Parsers produced by `lalr-scm' are now
- ;; stateful (e.g., they won't invoke the tokenizer any more once it has
- ;; returned `*eoi*'), hence the need to instantiate new parsers.
- (lalr-parser
- ;; terminal (i.e. input) token types
- (lbrace rbrace lparen rparen lbracket rbracket dot semicolon comma <
- > <= >= == != === !== + - * % ++ -- << >> >>> & bor ^ ! ~ && or ?
- colon = += -= *= %= <<= >>= >>>= &= bor= ^= / /=
- break else new var case finally return void catch for switch while
- continue function this with default if throw delete in try do
- instanceof typeof null true false
- Identifier StringLiteral NumericLiteral RegexpLiteral)
- (Program (SourceElements) : $1
- (*eoi*) : *eof-object*)
- ;;
- ;; Verily, here we define statements. Expressions are defined
- ;; afterwards.
- ;;
- (SourceElement (Statement) : $1
- (FunctionDeclaration) : $1)
- (FunctionDeclaration (function Identifier lparen rparen lbrace FunctionBody rbrace) : `(var (,$2 (lambda () ,$6)))
- (function Identifier lparen FormalParameterList rparen lbrace FunctionBody rbrace) : `(var (,$2 (lambda ,$4 ,$7))))
- (FunctionExpression (function lparen rparen lbrace FunctionBody rbrace) : `(lambda () ,$5)
- (function Identifier lparen rparen lbrace FunctionBody rbrace) : `(lambda () ,$6)
- (function lparen FormalParameterList rparen lbrace FunctionBody rbrace) : `(lambda ,$3 ,$6)
- (function Identifier lparen FormalParameterList rparen lbrace FunctionBody rbrace) : `(lambda ,$4 ,$7))
- (FormalParameterList (Identifier) : `(,$1)
- (FormalParameterList comma Identifier) : `(,@$1 ,$3))
- (SourceElements (SourceElement) : $1
- (SourceElements SourceElement) : (if (and (pair? $1) (eq? (car $1) 'begin))
- `(begin ,@(cdr $1) ,$2)
- `(begin ,$1 ,$2)))
- (FunctionBody (SourceElements) : $1
- () : '(begin))
- (Statement (Block) : $1
- (VariableStatement) : $1
- (EmptyStatement) : $1
- (ExpressionStatement) : $1
- (IfStatement) : $1
- (IterationStatement) : $1
- (ContinueStatement) : $1
- (BreakStatement) : $1
- (ReturnStatement) : $1
- (WithStatement) : $1
- (LabelledStatement) : $1
- (SwitchStatement) : $1
- (ThrowStatement) : $1
- (TryStatement) : $1)
- (Block (lbrace StatementList rbrace) : `(block ,$2))
- (StatementList (Statement) : $1
- (StatementList Statement) : (if (and (pair? $1) (eq? (car $1) 'begin))
- `(begin ,@(cdr $1) ,$2)
- `(begin ,$1 ,$2)))
- (VariableStatement (var VariableDeclarationList) : `(var ,@$2))
- (VariableDeclarationList (VariableDeclaration) : `(,$1)
- (VariableDeclarationList comma VariableDeclaration) : `(,@$1 ,$2))
- (VariableDeclarationListNoIn (VariableDeclarationNoIn) : `(,$1)
- (VariableDeclarationListNoIn comma VariableDeclarationNoIn) : `(,@$1 ,$2))
- (VariableDeclaration (Identifier) : `(,$1)
- (Identifier Initialiser) : `(,$1 ,$2))
- (VariableDeclarationNoIn (Identifier) : `(,$1)
- (Identifier Initialiser) : `(,$1 ,$2))
- (Initialiser (= AssignmentExpression) : $2)
- (InitialiserNoIn (= AssignmentExpressionNoIn) : $2)
- (EmptyStatement (semicolon) : '(begin))
- (ExpressionStatement (Expression semicolon) : $1)
- (IfStatement (if lparen Expression rparen Statement else Statement) : `(if ,$3 ,$5 ,$7)
- (if lparen Expression rparen Statement) : `(if ,$3 ,$5))
-
- (IterationStatement (do Statement while lparen Expression rparen semicolon) : `(do ,$2 ,$5)
- (while lparen Expression rparen Statement) : `(while ,$3 ,$5)
- (for lparen semicolon semicolon rparen Statement) : `(for #f #f #f ,$6)
- (for lparen semicolon semicolon Expression rparen Statement) : `(for #f #f ,$5 ,$7)
- (for lparen semicolon Expression semicolon rparen Statement) : `(for #f ,$4 #f ,$7)
- (for lparen semicolon Expression semicolon Expression rparen Statement) : `(for #f ,$4 ,$6 ,$8)
- (for lparen ExpressionNoIn semicolon semicolon rparen Statement) : `(for ,$3 #f #f ,$7)
- (for lparen ExpressionNoIn semicolon semicolon Expression rparen Statement) : `(for ,$3 #f ,$6 ,$8)
- (for lparen ExpressionNoIn semicolon Expression semicolon rparen Statement) : `(for ,$3 ,$5 #f ,$8)
- (for lparen ExpressionNoIn semicolon Expression semicolon Expression rparen Statement) : `(for ,$3 ,$5 ,$7 ,$9)
- (for lparen var VariableDeclarationListNoIn semicolon semicolon rparen Statement) : `(for (var ,@$4) #f #f ,$8)
- (for lparen var VariableDeclarationListNoIn semicolon semicolon Expression rparen Statement) : `(for (var ,@$4) #f ,$7 ,$9)
- (for lparen var VariableDeclarationListNoIn semicolon Expression semicolon rparen Statement) : `(for (var ,@$4) ,$6 #f ,$9)
- (for lparen var VariableDeclarationListNoIn semicolon Expression semicolon Expression rparen Statement) : `(for (var ,@$4) ,$6 ,$8 ,$10)
- (for lparen LeftHandSideExpression in Expression rparen Statement) : `(for-in ,$3 ,$5 ,$7)
- (for lparen var VariableDeclarationNoIn in Expression rparen Statement) : `(begin (var ,$4) (for-in (ref ,@$4) ,$6 ,$8)))
- (ContinueStatement (continue Identifier semicolon) : `(continue ,$2)
- (continue semicolon) : `(continue))
- (BreakStatement (break Identifier semicolon) : `(break ,$2)
- (break semicolon) : `(break))
- (ReturnStatement (return Expression semicolon) : `(return ,$2)
- (return semicolon) : `(return))
- (WithStatement (with lparen Expression rparen Statement) : `(with ,$3 ,$5))
- (SwitchStatement (switch lparen Expression rparen CaseBlock) : `(switch ,$3 ,@$5))
- (CaseBlock (lbrace rbrace) : '()
- (lbrace CaseClauses rbrace) : $2
- (lbrace CaseClauses DefaultClause rbrace) : `(,@$2 ,@$3)
- (lbrace DefaultClause rbrace) : `(,$2)
- (lbrace DefaultClause CaseClauses rbrace) : `(,@$2 ,@$3))
- (CaseClauses (CaseClause) : `(,$1)
- (CaseClauses CaseClause) : `(,@$1 ,$2))
- (CaseClause (case Expression colon) : `(case ,$2)
- (case Expression colon StatementList) : `(case ,$2 ,$4))
- (DefaultClause (default colon) : `(default)
- (default colon StatementList) : `(default ,$3))
- (LabelledStatement (Identifier colon Statement) : `(label ,$1 ,$3))
- (ThrowStatement (throw Expression semicolon) : `(throw ,$2))
- (TryStatement (try Block Catch) : `(try ,$2 ,$3 #f)
- (try Block Finally) : `(try ,$2 #f ,$3)
- (try Block Catch Finally) : `(try ,$2 ,$3 ,$4))
- (Catch (catch lparen Identifier rparen Block) : `(catch ,$3 ,$5))
- (Finally (finally Block) : `(finally ,$2))
- ;;
- ;; As promised, expressions. We build up to Expression bottom-up, so
- ;; as to get operator precedence right.
- ;;
- (PrimaryExpression (this) : 'this
- (null) : 'null
- (true) : 'true
- (false) : 'false
- (Identifier) : `(ref ,$1)
- (StringLiteral) : `(string ,$1)
- (RegexpLiteral) : `(regexp ,$1)
- (NumericLiteral) : `(number ,$1)
- (dot NumericLiteral) : `(number ,(string->number (string-append "." (number->string $2))))
- (ArrayLiteral) : $1
- (ObjectLiteral) : $1
- (lparen Expression rparen) : $2)
- (ArrayLiteral (lbracket rbracket) : '(array)
- (lbracket Elision rbracket) : '(array ,@$2)
- (lbracket ElementList rbracket) : `(array ,@$2)
- (lbracket ElementList comma rbracket) : `(array ,@$2)
- (lbracket ElementList comma Elision rbracket) : `(array ,@$2))
- (ElementList (AssignmentExpression) : `(,$1)
- (Elision AssignmentExpression) : `(,@$1 ,$2)
- (ElementList comma AssignmentExpression) : `(,@$1 ,$3)
- (ElementList comma Elision AssignmentExpression) : `(,@$1 ,@$3 ,$4))
- (Elision (comma) : '((number 0))
- (Elision comma) : `(,@$1 (number 0)))
- (ObjectLiteral (lbrace rbrace) : `(object)
- (lbrace PropertyNameAndValueList rbrace) : `(object ,@$2))
- (PropertyNameAndValueList (PropertyName colon AssignmentExpression) : `((,$1 ,$3))
- (PropertyNameAndValueList comma PropertyName colon AssignmentExpression) : `(,@$1 (,$3 ,$5)))
- (PropertyName (Identifier) : $1
- (StringLiteral) : (string->symbol $1)
- (NumericLiteral) : $1)
- (MemberExpression (PrimaryExpression) : $1
- (FunctionExpression) : $1
- (MemberExpression lbracket Expression rbracket) : `(aref ,$1 ,$3)
- (MemberExpression dot Identifier) : `(pref ,$1 ,$3)
- (new MemberExpression Arguments) : `(new ,$2 ,$3))
- (NewExpression (MemberExpression) : $1
- (new NewExpression) : `(new ,$2 ()))
- (CallExpression (MemberExpression Arguments) : `(call ,$1 ,$2)
- (CallExpression Arguments) : `(call ,$1 ,$2)
- (CallExpression lbracket Expression rbracket) : `(aref ,$1 ,$3)
- (CallExpression dot Identifier) : `(pref ,$1 ,$3))
- (Arguments (lparen rparen) : '()
- (lparen ArgumentList rparen) : $2)
- (ArgumentList (AssignmentExpression) : `(,$1)
- (ArgumentList comma AssignmentExpression) : `(,@$1 ,$3))
- (LeftHandSideExpression (NewExpression) : $1
- (CallExpression) : $1)
- (PostfixExpression (LeftHandSideExpression) : $1
- (LeftHandSideExpression ++) : `(postinc ,$1)
- (LeftHandSideExpression --) : `(postdec ,$1))
- (UnaryExpression (PostfixExpression) : $1
- (delete UnaryExpression) : `(delete ,$2)
- (void UnaryExpression) : `(void ,$2)
- (typeof UnaryExpression) : `(typeof ,$2)
- (++ UnaryExpression) : `(preinc ,$2)
- (-- UnaryExpression) : `(predec ,$2)
- (+ UnaryExpression) : `(+ ,$2)
- (- UnaryExpression) : `(- ,$2)
- (~ UnaryExpression) : `(~ ,$2)
- (! UnaryExpression) : `(! ,$2))
- (MultiplicativeExpression (UnaryExpression) : $1
- (MultiplicativeExpression * UnaryExpression) : `(* ,$1 ,$3)
- (MultiplicativeExpression / UnaryExpression) : `(/ ,$1 ,$3)
- (MultiplicativeExpression % UnaryExpression) : `(% ,$1 ,$3))
- (AdditiveExpression (MultiplicativeExpression) : $1
- (AdditiveExpression + MultiplicativeExpression) : `(+ ,$1 ,$3)
- (AdditiveExpression - MultiplicativeExpression) : `(- ,$1 ,$3))
- (ShiftExpression (AdditiveExpression) : $1
- (ShiftExpression << MultiplicativeExpression) : `(<< ,$1 ,$3)
- (ShiftExpression >> MultiplicativeExpression) : `(>> ,$1 ,$3)
- (ShiftExpression >>> MultiplicativeExpression) : `(>>> ,$1 ,$3))
- (RelationalExpression (ShiftExpression) : $1
- (RelationalExpression < ShiftExpression) : `(< ,$1 ,$3)
- (RelationalExpression > ShiftExpression) : `(> ,$1 ,$3)
- (RelationalExpression <= ShiftExpression) : `(<= ,$1 ,$3)
- (RelationalExpression >= ShiftExpression) : `(>= ,$1 ,$3)
- (RelationalExpression instanceof ShiftExpression) : `(instanceof ,$1 ,$3)
- (RelationalExpression in ShiftExpression) : `(in ,$1 ,$3))
- (RelationalExpressionNoIn (ShiftExpression) : $1
- (RelationalExpressionNoIn < ShiftExpression) : `(< ,$1 ,$3)
- (RelationalExpressionNoIn > ShiftExpression) : `(> ,$1 ,$3)
- (RelationalExpressionNoIn <= ShiftExpression) : `(<= ,$1 ,$3)
- (RelationalExpressionNoIn >= ShiftExpression) : `(>= ,$1 ,$3)
- (RelationalExpressionNoIn instanceof ShiftExpression) : `(instanceof ,$1 ,$3))
- (EqualityExpression (RelationalExpression) : $1
- (EqualityExpression == RelationalExpression) : `(== ,$1 ,$3)
- (EqualityExpression != RelationalExpression) : `(!= ,$1 ,$3)
- (EqualityExpression === RelationalExpression) : `(=== ,$1 ,$3)
- (EqualityExpression !== RelationalExpression) : `(!== ,$1 ,$3))
- (EqualityExpressionNoIn (RelationalExpressionNoIn) : $1
- (EqualityExpressionNoIn == RelationalExpressionNoIn) : `(== ,$1 ,$3)
- (EqualityExpressionNoIn != RelationalExpressionNoIn) : `(!= ,$1 ,$3)
- (EqualityExpressionNoIn === RelationalExpressionNoIn) : `(=== ,$1 ,$3)
- (EqualityExpressionNoIn !== RelationalExpressionNoIn) : `(!== ,$1 ,$3))
- (BitwiseANDExpression (EqualityExpression) : $1
- (BitwiseANDExpression & EqualityExpression) : `(& ,$1 ,$3))
- (BitwiseANDExpressionNoIn (EqualityExpressionNoIn) : $1
- (BitwiseANDExpressionNoIn & EqualityExpressionNoIn) : `(& ,$1 ,$3))
- (BitwiseXORExpression (BitwiseANDExpression) : $1
- (BitwiseXORExpression ^ BitwiseANDExpression) : `(^ ,$1 ,$3))
- (BitwiseXORExpressionNoIn (BitwiseANDExpressionNoIn) : $1
- (BitwiseXORExpressionNoIn ^ BitwiseANDExpressionNoIn) : `(^ ,$1 ,$3))
- (BitwiseORExpression (BitwiseXORExpression) : $1
- (BitwiseORExpression bor BitwiseXORExpression) : `(bor ,$1 ,$3))
- (BitwiseORExpressionNoIn (BitwiseXORExpressionNoIn) : $1
- (BitwiseORExpressionNoIn bor BitwiseXORExpressionNoIn) : `(bor ,$1 ,$3))
- (LogicalANDExpression (BitwiseORExpression) : $1
- (LogicalANDExpression && BitwiseORExpression) : `(and ,$1 ,$3))
- (LogicalANDExpressionNoIn (BitwiseORExpressionNoIn) : $1
- (LogicalANDExpressionNoIn && BitwiseORExpressionNoIn) : `(and ,$1 ,$3))
- (LogicalORExpression (LogicalANDExpression) : $1
- (LogicalORExpression or LogicalANDExpression) : `(or ,$1 ,$3))
- (LogicalORExpressionNoIn (LogicalANDExpressionNoIn) : $1
- (LogicalORExpressionNoIn or LogicalANDExpressionNoIn) : `(or ,$1 ,$3))
- (ConditionalExpression (LogicalORExpression) : $1
- (LogicalORExpression ? AssignmentExpression colon AssignmentExpression) : `(if ,$1 ,$3 ,$5))
- (ConditionalExpressionNoIn (LogicalORExpressionNoIn) : $1
- (LogicalORExpressionNoIn ? AssignmentExpressionNoIn colon AssignmentExpressionNoIn) : `(if ,$1 ,$3 ,$5))
- (AssignmentExpression (ConditionalExpression) : $1
- (LeftHandSideExpression AssignmentOperator AssignmentExpression) : `(,$2 ,$1 ,$3))
- (AssignmentExpressionNoIn (ConditionalExpressionNoIn) : $1
- (LeftHandSideExpression AssignmentOperator AssignmentExpressionNoIn) : `(,$2 ,$1 ,$3))
- (AssignmentOperator (=) : '=
- (*=) : '*=
- (/=) : '/=
- (%=) : '%=
- (+=) : '+=
- (-=) : '-=
- (<<=) : '<<=
- (>>=) : '>>=
- (>>>=) : '>>>=
- (&=) : '&=
- (^=) : '^=
- (bor=) : 'bor=)
- (Expression (AssignmentExpression) : $1
- (Expression comma AssignmentExpression) : `(begin ,$1 ,$3))
- (ExpressionNoIn (AssignmentExpressionNoIn) : $1
- (ExpressionNoIn comma AssignmentExpressionNoIn) : `(begin ,$1 ,$3))))
|