language-javascript-0.5.14.2/0000755000000000000000000000000012557503314014063 5ustar0000000000000000language-javascript-0.5.14.2/language-javascript.cabal0000644000000000000000000000656212557503314021007 0ustar0000000000000000Name: language-javascript Version: 0.5.14.2 Synopsis: Parser for JavaScript Description: Parses Javascript into an Abstract Syntax Tree (AST). Initially intended as frontend to hjsmin. . Note: Version 0.5.0 breaks compatibility with prior versions, the AST has been reworked to allow round trip processing of JavaScript. Homepage: https://github.com/erikd/language-javascript License: BSD3 License-file: LICENSE Author: Alan Zimmerman Maintainer: Erik de Castro Lopo Copyright: (c) 2010-2015 Alan Zimmerman, 2015 Erik de Castro Lopo Category: Language Build-type: Simple homepage: http://github.com/erikd/language-javascript bug-reports: http://github.com/erikd/language-javascript/issues Extra-source-files: README.md .ghci buildall.sh test/Unicode.js test/k.js test/unicode.txt -- runalex.sh src/Language/JavaScript/Parser/Lexer.x -- Version requirement upped for test support in later Cabal Cabal-version: >= 1.9.2 Library Build-depends: base >= 4 && < 5 , array >= 0.3 , mtl >= 1.1 , containers >= 0.2 -- For the round trip output , blaze-builder >= 0.2 , bytestring >= 0.9.1 , utf8-string >= 0.3.7 && < 2 if impl(ghc >= 7.10) build-tools: happy >= 1.19, alex >= 3.1.4 else if impl(ghc >= 7.8) build-tools: happy >= 1.19, alex >= 3.1 else build-tools: happy >= 1.18.5, alex >= 3.0.5 hs-source-dirs: src Exposed-modules: Language.JavaScript.Parser Language.JavaScript.Parser.Parser Language.JavaScript.Parser.Lexer Language.JavaScript.Parser.Grammar5 Language.JavaScript.Parser.AST Language.JavaScript.Pretty.Printer Language.JavaScript.Parser.SrcLocation Other-modules: Language.JavaScript.Parser.LexerUtils Language.JavaScript.Parser.ParseError Language.JavaScript.Parser.ParserMonad Language.JavaScript.Parser.StringEscape Language.JavaScript.Parser.Token ghc-options: -Wall Test-Suite test-language-javascript Type: exitcode-stdio-1.0 Main-is: runtests.hs build-depends: base, Cabal >= 1.9.2 , QuickCheck >= 2 , HUnit , test-framework-hunit , test-framework , array >= 0.3 , utf8-light >= 0.4 , containers >= 0.2 , mtl >= 1.1 , utf8-string >= 0.3.7 && < 2 , bytestring >= 0.9.1 , blaze-builder >= 0.2 -- need our own library for tests , language-javascript >= 0.5.5 source-repository head type: git location: https://github.com/erikd/language-javascript.git language-javascript-0.5.14.2/.ghci0000644000000000000000000000021012557503314014767 0ustar0000000000000000-- Startup commands for the GHC interpreter :set -hide-package monads-tf :set -hide-package monads-fd :set -i./src :set -i./dist/build language-javascript-0.5.14.2/Setup.hs0000644000000000000000000000005612557503314015520 0ustar0000000000000000import Distribution.Simple main = defaultMain language-javascript-0.5.14.2/README.md0000644000000000000000000001170212557503314015343 0ustar0000000000000000Parser for JavaScript --------------------- [![Build Status](https://secure.travis-ci.org/alanz/language-javascript.png?branch=master)](http://travis-ci.org/alanz/language-javascript) Based (loosely) on language-python How to build ------------ Library: cabal clean && cabal configure && cabal build Tests: cabal clean && cabal configure -fbuildtests && cabal build Running the tests ./dist/build/runtests/runtests To debug the grammar happy -iparse.txt -g -a -d src/Language/JavaScript/Parser/Grammar5.y This generates src/Language/JavaScript/Parser/Grammar.hs, delete this when done with the debug version UTF8/Unicode version -------------------- Alex 3.0 now supports unicode natively, and has been included as a dependency in the cabal file. Note: The generation of the lexical analyser has been separated out, to remove the install-time dependency on Alex. If any changes need to be made to the lexer, the Lexer.x source lies in src-dev, and the runalex.sh script will invoke Alex with the appropriate directories. Changes ------- ``` 0.5.14.2 Update Alex dependency 0.5.14.1 Fix haddocks 0.5.14.0 Fix a break/continue/return parsing problem 0.5.13.3 Fix utf8-string lower bound typo no 2 0.5.13.2 Fix utf8-string lower bound typo 0.5.13.1 Bump utf8-string dependency upper bound, and loosen others 0.5.13 Put GHC 7.8.x -specific alex and happy versions, thanks @simonmichael 0.5.12 Put dependency on alex >= 3.0.5 in the cabal file, thanks @peti 0.5.11 Remove pre-generated Lexer.hs as it does not work will all versions of GHC. This means a current alex will have to be installed before this package can be installed. 0.5.10 Bring in alex 3.1.3, allowing compatibility with GHC 7.8 0.5.9 Relax array dependency for GHC 7.8.1, thanks @maoe 0.5.8 Fixed compilation issue using GHC 7.6.3 on Mac OSX, thanks @albertov 0.5.7 Remove the hs-source-dirs from test suite to prevent compilation issues (@nomeata) Introduce parseFileUtf8 to explicitly use utf8 for parsing a file, and update tests to use it where needed. Closes #21 0.5.6 Remove constraint on Alex 3.0.1, it is only required to make changes to the lexer. Closes #19 0.5.5 Updated version ranges for GHC 7.6.1, courtesy of @mietek Note: requires alex 3.0.1 for development (not install) 0.5.4 Fixed bug where lexer switches to regexp mode after a ']' char, reported by @aszlig 0.5.3 Merge pull requests from @aszlig to add octal support, and to allow leading zeros in exponents 0.5.2 Merged pull request from @markwright added some missing test files to the cabal file. Added runalex.sh and Lexer.x to the cabal file. 0.5.1 Export CommentAnnotation(..). Simplify AST by getting rid of JSFunctionBody, JSSourceElements, JSStatementBlock, JSStatementList. They are replaced by JSBlock or a simple list. Also fix lexer mode in presence of whitespace. Changed way tests are invoked, to allow Travis integration. 0.5.0 Rework AST to allow full round-trip parsing and output of JavaScript. Breaks AST compatibility with prior versions 0.4.10 Moved Lexer.x into a separate directory, and made a script to call alex to generate Lexer.hs. This means alex is not required at install time 0.4.9 Make alex and happy versions more explicit. Expose the AlexSpan data type, so parse error positions can be reported. 0.4.8 Close issue https://github.com/alanz/language-javascript/issues/5 by correcting the lexical analyser for DecimalLiteral 0.4.7 Continue ECMASCRIPT update, remove incorrect future reserved words for "code", "mode", "of", "one", "or" and "strict", put in by accident/stupidity. 0.4.6 Update to ECMASCRIPT 5.1 by allowing continuations in string literals Include build dependencies on alex >= 3.0 and happy. 0.4.5 Update cabal file and docs for Alex 3.0, giving out of the box unicode support 0.4.4 Allow unicode characters in comments 0.4.3 correct lexer for decimalToken, only leading digit needs to be non-zero. 0.4.2 Expose SrcSpan 0.4.1 Expose AST.Node as well. 0.4.0 Updated JSNode to include location information, and made the parse more true to the original by leaving blocks as such, not replacing with ';'. 0.3.0 ECMA-262 edition 5 compliance. Required adding JSFunctionExpression and JSPropertyAccessor to the AST. 0.2.2 Heading toward compliance with edition 5. Trailing commas allowed in array literals too. 0.2.1 Allow trailing comma in object literal 0.2.0 ECMAScript 3 allows function expressions to have names, AST.JSFunctionExpression now reflects this 0.1.0 Simplified AST by removing JSElement and JSElementList components 0.0.3 Support for unicode in source. At the moment it only supports UTF8 encoding, does not recognise byte order marks or UTF-16/UTF-32 0.0.2 Multiline comments were processed in greedy form, now end of comment recognised properly. Thanks to Tony Morris for reporting this. 0.0.1 Initial release ``` EOF language-javascript-0.5.14.2/buildall.sh0000755000000000000000000000044312557503314016213 0ustar0000000000000000#!/bin/sh # First run alex on Lexer.x to generate Lexer.hs #./runalex.sh # do a clean build of all, including the tests #cabal clean && cabal configure -fbuildtests && cabal build && cabal haddock cabal clean && cabal configure --enable-tests && cabal build && cabal test && cabal haddock language-javascript-0.5.14.2/runtests.hs0000644000000000000000000022002512557503314016307 0ustar0000000000000000 import Language.JavaScript.Parser import Language.JavaScript.Parser.Grammar5 import Language.JavaScript.Parser.Lexer import Language.JavaScript.Parser.Parser import Data.List (intercalate) import Test.Framework (defaultMain, testGroup, Test) import Test.Framework.Providers.HUnit import Test.HUnit hiding (Test) main :: IO () main = defaultMain [ lexerSuite , parserSuite -- ++AZ++temporary++ , commentSuite , commentPrintSuite , pendingSuite ] pendingSuite :: Test pendingSuite = testGroup "Pending" [ ] lexerSuite:: Test lexerSuite = testGroup "Lexer" [ testCase "assign1" (testLexer "x=1" "[IdentifierToken,SimpleAssignToken,DecimalToken]") , testCase "assign2" (testLexer "x=1\ny=2" "[IdentifierToken,SimpleAssignToken,DecimalToken,WsToken,IdentifierToken,SimpleAssignToken,DecimalToken]") , testCase "break" (testLexer "break\nx=1" "[BreakToken,WsToken,IdentifierToken,SimpleAssignToken,DecimalToken]") , testCase "return" (testLexer "return\nx=1" "[ReturnToken,WsToken,IdentifierToken,SimpleAssignToken,DecimalToken]") ] parserSuite :: Test parserSuite = testGroup "Parser" [ testCase "helloWorld" caseHelloWorld , testCase "LiteralNull" (testLiteral "null" "Right (JSLiteral \"null\")") , testCase "LiteralFalse" (testLiteral "false" "Right (JSLiteral \"false\")") , testCase "LiteralTrue" (testLiteral "true" "Right (JSLiteral \"true\")") , testCase "LiteralHexInteger1" (testLiteral "0x1234fF" "Right (JSHexInteger \"0x1234fF\")") , testCase "LiteralHexInteger2" (testLiteral "0X1234fF" "Right (JSHexInteger \"0X1234fF\")") , testCase "LiteralDecimal1" (testLiteral "1.0e4" "Right (JSDecimal \"1.0e4\")") , testCase "LiteralDecimal2" (testLiteral "2.3E6" "Right (JSDecimal \"2.3E6\")") , testCase "LiteralDecimal3" (testLiteral "4.5" "Right (JSDecimal \"4.5\")") , testCase "LiteralDecimal3" (testLiteral "0.7e8" "Right (JSDecimal \"0.7e8\")") , testCase "LiteralDecimal4" (testLiteral "0.7E8" "Right (JSDecimal \"0.7E8\")") , testCase "LiteralDecimal5" (testLiteral "10" "Right (JSDecimal \"10\")") , testCase "LiteralDecimal6" (testLiteral "0" "Right (JSDecimal \"0\")") , testCase "LiteralDecimal7" (testLiteral "0.03" "Right (JSDecimal \"0.03\")") , testCase "LiteralDecimal9" (testLiteral "0.7e+8" "Right (JSDecimal \"0.7e+8\")") , testCase "LiteralDecimal10" (testLiteral "0.7e-18" "Right (JSDecimal \"0.7e-18\")") , testCase "LiteralDecimal11" (testLiteral "1.0e+4" "Right (JSDecimal \"1.0e+4\")") , testCase "LiteralDecimal12" (testLiteral "1.0e-4" "Right (JSDecimal \"1.0e-4\")") , testCase "LiteralDecimal13" (testLiteral "1e18" "Right (JSDecimal \"1e18\")") , testCase "LiteralDecimal14" (testLiteral "1e+18" "Right (JSDecimal \"1e+18\")") , testCase "LiteralDecimal15" (testLiteral "1e-18" "Right (JSDecimal \"1e-18\")") , testCase "LiteralDecimal16" (testLiteral "1E-01" "Right (JSDecimal \"1E-01\")") , testCase "LiteralOctal" (testLiteral "010" "Right (JSOctal \"010\")") , testCase "LiteralString1" (testLiteral "\"hello\\nworld\"" "Right (JSStringLiteral '\"' \"hello\\\\nworld\")") , testCase "LiteralString2" (testLiteral "'hello\\nworld'" "Right (JSStringLiteral '\\'' \"hello\\\\nworld\")") , testCase "LiteralThis" (testPE "this" "Right (JSLiteral \"this\")") , testCase "LiteralRegex1" (testPE "/blah/" "Right (JSRegEx \"/blah/\")") , testCase "LiteralRegex2" (testPE "/$/g" "Right (JSRegEx \"/$/g\")") , testCase "LiteralRegex3" (testPE "/\\n/g" "Right (JSRegEx \"/\\\\n/g\")") , testCase "LiteralRegex4" (testPE "/^\"(?:\\.|[^\"])*\"|^'(?:[^']|\\.)*'/" "Right (JSRegEx \"/^\\\"(?:\\\\.|[^\\\"])*\\\"|^'(?:[^']|\\\\.)*'/\")") , testCase "Identifier1" (testPE "_$" "Right (JSIdentifier \"_$\")") , testCase "Identifier2" (testPE "this_" "Right (JSIdentifier \"this_\")") , testCase "ArrayLiteral1" (testPE "[]" "Right (JSArrayLiteral [])") , testCase "ArrayLiteral2" (testPE "[,]" "Right (JSArrayLiteral [JSElision JSLiteral \",\"])") , testCase "ArrayLiteral3" (testPE "[,,]" "Right (JSArrayLiteral [JSElision JSLiteral \",\",JSElision JSLiteral \",\"])") , testCase "ArrayLiteral4" (testPE "[,,x]" "Right (JSArrayLiteral [JSElision JSLiteral \",\",JSElision JSLiteral \",\",JSIdentifier \"x\"])") , testCase "ArrayLiteral5" (testPE "[,,x]" "Right (JSArrayLiteral [JSElision JSLiteral \",\",JSElision JSLiteral \",\",JSIdentifier \"x\"])") , testCase "ArrayLiteral6" (testPE "[,x,,x]" "Right (JSArrayLiteral [JSElision JSLiteral \",\",JSIdentifier \"x\",JSElision JSLiteral \",\",JSElision JSLiteral \",\",JSIdentifier \"x\"])") , testCase "ArrayLiteral7" (testPE "[x]" "Right (JSArrayLiteral [JSIdentifier \"x\"])") , testCase "ArrayLiteral8" (testPE "[x,]" "Right (JSArrayLiteral [JSIdentifier \"x\",JSLiteral \",\"])") , testCase "ObjectLiteral1" (testPE "{}" "Right (JSObjectLiteral [])") , testCase "ObjectLiteral2" (testPE "{x:1}" "Right (JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"x\") [JSDecimal \"1\"]])") , testCase "ObjectLiteral3" (testPE "{x:1,y:2}" "Right (JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"x\") [JSDecimal \"1\"],JSLiteral \",\",JSPropertyNameandValue (JSIdentifier \"y\") [JSDecimal \"2\"]])") , testCase "ObjectLiteral4" (testPE "{evaluate:evaluate,load:function load(s){if(x)return s;1}}" "Right (JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"evaluate\") [JSIdentifier \"evaluate\"],JSLiteral \",\",JSPropertyNameandValue (JSIdentifier \"load\") [JSFunctionExpression [JSIdentifier \"load\"] [JSIdentifier \"s\"] (JSBlock ([JSIf (JSExpression [JSIdentifier \"x\"]) ([JSReturn [JSExpression [JSIdentifier \"s\"]] JSLiteral \";\"]) ([]),JSExpression [JSDecimal \"1\"]]))]])") , testCase "ObjectLiteral5" (testPE "{x:1,}" "Right (JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"x\") [JSDecimal \"1\"],JSLiteral \",\"])") , testCase "ObjectLiteral6" (testProg "a={\n values: 7,\n}\n" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"a\",JSOperator JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"values\") [JSDecimal \"7\"],JSLiteral \",\"]],JSLiteral \"\"])") -- Edition 5 extensions , testCase "ObjectLiteral7" (testProg "x={get foo() {return 1},set foo(a) {x=a}}" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSObjectLiteral [JSPropertyAccessor NT (JSLiteral \"get\") (TokenPn 3 1 4) [NoComment] (JSIdentifier \"foo\") [] (JSBlock ([JSReturn [JSExpression [JSDecimal \"1\"]] JSLiteral \"\"])),JSLiteral \",\",JSPropertyAccessor NT (JSLiteral \"set\") (TokenPn 24 1 25) [NoComment] (JSIdentifier \"foo\") [JSIdentifier \"a\"] (JSBlock ([JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSIdentifier \"a\"]]))]],JSLiteral \"\"])") , testCase "ObjectLiteral8" (testProg "a={if:1,interface:2}" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"a\",JSOperator JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"if\") [JSDecimal \"1\"],JSLiteral \",\",JSPropertyNameandValue (JSIdentifier \"interface\") [JSDecimal \"2\"]]],JSLiteral \"\"])") , testCase "ExpressionParen" (testPE "(56)" "Right (JSExpressionParen (JSExpression [JSDecimal \"56\"]))") , testCase "Statement1" (testStmt "x" "Right (JSExpression [JSIdentifier \"x\"])") , testCase "Statement2" (testStmt "null" "Right (JSExpression [JSLiteral \"null\"])") , testCase "Statement3" (testStmt "true?1:2" "Right (JSExpression [JSExpressionTernary [JSLiteral \"true\"] [JSDecimal \"1\"] [JSDecimal \"2\"]])") , testCase "Statement4" (testStmt "x||y" "Right (JSExpression [JSExpressionBinary \"||\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement5" (testStmt "x&&y" "Right (JSExpression [JSExpressionBinary \"&&\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement6" (testStmt "x|y" "Right (JSExpression [JSExpressionBinary \"|\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement6" (testStmt "x^y" "Right (JSExpression [JSExpressionBinary \"^\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement7" (testStmt "x&y" "Right (JSExpression [JSExpressionBinary \"&\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement8" (testStmt "x==y" "Right (JSExpression [JSExpressionBinary \"==\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement9" (testStmt "x!=y" "Right (JSExpression [JSExpressionBinary \"!=\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement10" (testStmt "x===y" "Right (JSExpression [JSExpressionBinary \"===\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement11" (testStmt "x!==y" "Right (JSExpression [JSExpressionBinary \"!==\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement12" (testStmt "xy" "Right (JSExpression [JSExpressionBinary \">\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement12" (testStmt "x<=y" "Right (JSExpression [JSExpressionBinary \"<=\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement12" (testStmt "x>=y" "Right (JSExpression [JSExpressionBinary \">=\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") -- , testCase "Statement12" (testStmt "x instanceof y" "") -- TODO: restore test case , testCase "Statement13" (testStmt "x<>y" "Right (JSExpression [JSExpressionBinary \">>\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement13" (testStmt "x>>>y" "Right (JSExpression [JSExpressionBinary \">>>\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement14" (testStmt "x+y" "Right (JSExpression [JSExpressionBinary \"+\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement14" (testStmt "x-y" "Right (JSExpression [JSExpressionBinary \"-\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement15" (testStmt "x*y" "Right (JSExpression [JSExpressionBinary \"*\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement16" (testStmt "x/y" "Right (JSExpression [JSExpressionBinary \"/\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement17" (testStmt "x%y" "Right (JSExpression [JSExpressionBinary \"%\" [JSIdentifier \"x\"] [JSIdentifier \"y\"]])") , testCase "Statement18" (testStmt "delete y" "Right (JSExpression [JSUnary \"delete \",JSIdentifier \"y\"])") , testCase "Statement19" (testStmt "void y" "Right (JSExpression [JSUnary \"void \",JSIdentifier \"y\"])") , testCase "Statement20" (testStmt "typeof y" "Right (JSExpression [JSUnary \"typeof \",JSIdentifier \"y\"])") , testCase "Statement21" (testStmt "++y" "Right (JSExpression [JSUnary \"++\",JSIdentifier \"y\"])") , testCase "Statement22" (testStmt "--y" "Right (JSExpression [JSUnary \"--\",JSIdentifier \"y\"])") , testCase "Statement23" (testStmt "+y" "Right (JSExpression [JSUnary \"+\",JSIdentifier \"y\"])") , testCase "Statement24" (testStmt "-y" "Right (JSExpression [JSUnary \"-\",JSIdentifier \"y\"])") , testCase "Statement25" (testStmt "~y" "Right (JSExpression [JSUnary \"~\",JSIdentifier \"y\"])") , testCase "Statement26" (testStmt "!y" "Right (JSExpression [JSUnary \"!\",JSIdentifier \"y\"])") , testCase "Statement27" (testStmt "y++" "Right (JSExpression [JSExpressionPostfix \"++\" [JSIdentifier \"y\"]])") , testCase "Statement28" (testStmt "y--" "Right (JSExpression [JSExpressionPostfix \"--\" [JSIdentifier \"y\"]])") -- Member Expressions , testCase "MemberExpression1a" (testStmt "function(){}" "Right (JSExpression [JSFunctionExpression [] [] (JSBlock ([]))])") , testCase "MemberExpression1b" (testStmt "function(a){}" "Right (JSExpression [JSFunctionExpression [] [JSIdentifier \"a\"] (JSBlock ([]))])") , testCase "MemberExpression1c" (testStmt "function(a,b){}" "Right (JSExpression [JSFunctionExpression [] [JSIdentifier \"a\",JSLiteral \",\",JSIdentifier \"b\"] (JSBlock ([]))])") , testCase "MemberExpression1d" (testStmt "x[y]" "Right (JSExpression [JSMemberSquare [JSIdentifier \"x\"] (JSExpression [JSIdentifier \"y\"])])") , testCase "MemberExpression1e" (testStmt "x[y][z]" "Right (JSExpression [JSMemberSquare [JSMemberSquare [JSIdentifier \"x\"] (JSExpression [JSIdentifier \"y\"])] (JSExpression [JSIdentifier \"z\"])])") , testCase "MemberExpression1f" (testStmt "x.y" "Right (JSExpression [JSMemberDot [JSIdentifier \"x\"] (JSIdentifier \"y\")])") , testCase "MemberExpression1g" (testStmt "x.y.z" "Right (JSExpression [JSMemberDot [JSMemberDot [JSIdentifier \"x\"] (JSIdentifier \"y\")] (JSIdentifier \"z\")])") , testCase "MemberExpression1h" (testStmt "new x()" "Right (JSExpression [JSLiteral \"new\",JSIdentifier \"x\",JSArguments []])") , testCase "NewExpression1" (testStmt "new x.y" "Right (JSExpression [JSLiteral \"new\",JSMemberDot [JSIdentifier \"x\"] (JSIdentifier \"y\")])") , testCase "CallExpression1" (testStmt "x()" "Right (JSExpression [JSIdentifier \"x\",JSArguments []])") , testCase "CallExpression2" (testStmt "x()()" "Right (JSExpression [JSIdentifier \"x\",JSArguments [],JSCallExpression \"()\" [JSArguments []]])") , testCase "CallExpression3" (testStmt "x()[4]" "Right (JSExpression [JSIdentifier \"x\",JSArguments [],JSCallExpression \"[]\" [JSExpression [JSDecimal \"4\"]]])") , testCase "CallExpression4" (testStmt "x().x" "Right (JSExpression [JSIdentifier \"x\",JSArguments [],JSCallExpression \".\" [JSIdentifier \"x\"]])") , testCase "CallExpression5" (testStmt "x(a,b=2).x" "Right (JSExpression [JSIdentifier \"x\",JSArguments [JSIdentifier \"a\",JSLiteral \",\",JSIdentifier \"b\",JSOperator JSLiteral \"=\",JSDecimal \"2\"],JSCallExpression \".\" [JSIdentifier \"x\"]])") , testCase "AssignExpression1" (testStmt "x=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"])") , testCase "AssignExpression2" (testStmt "x*=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"*=\",JSDecimal \"1\"])") , testCase "AssignExpression3" (testStmt "x/=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"/=\",JSDecimal \"1\"])") , testCase "AssignExpression4" (testStmt "x%=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"%=\",JSDecimal \"1\"])") , testCase "AssignExpression5" (testStmt "x+=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"+=\",JSDecimal \"1\"])") , testCase "AssignExpression6" (testStmt "x-=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"-=\",JSDecimal \"1\"])") , testCase "AssignExpression7" (testStmt "x<<=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"<<=\",JSDecimal \"1\"])") , testCase "AssignExpression8" (testStmt "x>>=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \">>=\",JSDecimal \"1\"])") , testCase "AssignExpression9" (testStmt "x>>>=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \">>>=\",JSDecimal \"1\"])") , testCase "AssignExpression10" (testStmt "x&=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"&=\",JSDecimal \"1\"])") , testCase "AssignExpression11" (testStmt "x^=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"^=\",JSDecimal \"1\"])") , testCase "AssignExpression12" (testStmt "x|=1" "Right (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"|=\",JSDecimal \"1\"])") , testCase "Block1" (testStmt "{}" "Right (JSBlock ([]))") , testCase "Block2" (testStmt "{x=1}" "Right (JSBlock ([JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"]]))") , testCase "Block3" (testStmt "{x=1;y=2}" "Right (JSBlock ([JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSExpression [JSIdentifier \"y\",JSOperator JSLiteral \"=\",JSDecimal \"2\"]]))") , testCase "Block4" (testStmt "{{}}" "Right (JSBlock ([JSBlock ([])]))") , testCase "Block5" (testStmt "{{{}}}" "Right (JSBlock ([JSBlock ([JSBlock ([])])]))") , testCase "If1" (testStmt "if (1) {}" "Right (JSIf (JSExpression [JSDecimal \"1\"]) ([JSBlock ([])]) ([]))") , testCase "IfElse1" (testStmt "if (1) {} else {}" "Right (JSIf (JSExpression [JSDecimal \"1\"]) ([JSBlock ([])]) ([JSLiteral \"else\",JSBlock ([])]))") , testCase "IfElse2" (testStmt "if (1) x=1; else {}" "Right (JSIf (JSExpression [JSDecimal \"1\"]) ([JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\"]) ([JSLiteral \"else\",JSBlock ([])]))") , testCase "DoWhile1" (testStmt "do {x=1} while (true);" "Right (JSDoWhile (JSBlock ([JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"]])) (JSExpression [JSLiteral \"true\"]) (JSLiteral \";\"))") , testCase "DoWhile2" (testStmt "do x=x+1;while(x<4);" "Right (JSDoWhile (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSExpressionBinary \"+\" [JSIdentifier \"x\"] [JSDecimal \"1\"]]) (JSExpression [JSExpressionBinary \"<\" [JSIdentifier \"x\"] [JSDecimal \"4\"]]) (JSLiteral \";\"))") , testCase "While1" (testStmt "while(true);" "Right (JSWhile (JSExpression [JSLiteral \"true\"]) (JSLiteral \";\"))") , testCase "For1" (testStmt "for(;;);" "Right (JSFor [] [] [] (JSLiteral \";\"))") , testCase "For2" (testStmt "for(x=1;x<10;x++);" "Right (JSFor [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"]] [JSExpression [JSExpressionBinary \"<\" [JSIdentifier \"x\"] [JSDecimal \"10\"]]] [JSExpression [JSExpressionPostfix \"++\" [JSIdentifier \"x\"]]] (JSLiteral \";\"))") , testCase "ForVar1" (testStmt "for(var x;;);" "Right (JSForVar [JSVarDecl (JSIdentifier \"x\") []] [] [] (JSLiteral \";\"))") , testCase "ForVar2a" (testStmt "for(var x=1;;);" "Right (JSForVar [JSVarDecl (JSIdentifier \"x\") [JSLiteral \"=\",JSDecimal \"1\"]] [] [] (JSLiteral \";\"))") , testCase "ForVar2b" (testStmt "for(var x;y;z){}" "Right (JSForVar [JSVarDecl (JSIdentifier \"x\") []] [JSExpression [JSIdentifier \"y\"]] [JSExpression [JSIdentifier \"z\"]] (JSBlock ([])))") , testCase "ForIn1" (testStmt "for(x in 5){}" "Right (JSForIn [JSIdentifier \"x\"] (JSExpression [JSDecimal \"5\"]) (JSBlock ([])))") , testCase "ForVarIn1" (testStmt "for(var x in 5){}" "Right (JSForVarIn (JSVarDecl (JSIdentifier \"x\") []) (JSExpression [JSDecimal \"5\"]) (JSBlock ([])))") , testCase "Var1" (testStmt "var x=1;" "Right (JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"x\") [JSLiteral \"=\",JSDecimal \"1\"]])") , testCase "Var2" (testStmt "const x=1,y=2;" "Right (JSVariables JSLiteral \"const\" [JSVarDecl (JSIdentifier \"x\") [JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \",\",JSVarDecl (JSIdentifier \"y\") [JSLiteral \"=\",JSDecimal \"2\"]])") , testCase "Continue1" (testStmt "continue;" "Right (JSContinue [] JSLiteral \";\")") , testCase "Continue2" (testStmt "continue x;" "Right (JSContinue [JSIdentifier \"x\"] JSLiteral \";\")") , testCase "Break1" (testStmt "break;" "Right (JSBreak [] JSLiteral \";\")") , testCase "Break2" (testStmt "break x;" "Right (JSBreak [JSIdentifier \"x\"] JSLiteral \";\")") , testCase "Return1" (testStmt "return;" "Right (JSReturn [] JSLiteral \";\")") , testCase "Return2" (testStmt "return x;" "Right (JSReturn [JSExpression [JSIdentifier \"x\"]] JSLiteral \";\")") , testCase "With1" (testStmt "with (x) {};" "Right (JSWith (JSExpression [JSIdentifier \"x\"]) [JSBlock ([]),JSLiteral \";\"])") , testCase "Labelled1" (testStmt "abc:x=1" "Right (JSLabelled (JSIdentifier \"abc\") (JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"]))") , testCase "Switch1" (testStmt "switch (x) {}" "Right (JSSwitch (JSExpression [JSIdentifier \"x\"]) JSBlock ([JSLiteral \"\"]))") , testCase "Switch2" (testStmt "switch (x) {case 1:break;}" "Right (JSSwitch (JSExpression [JSIdentifier \"x\"]) JSBlock ([JSCase (JSExpression [JSDecimal \"1\"]) ([JSBreak [] JSLiteral \";\"])]))") , testCase "Switch3" (testStmt "switch (x) {case 0:\ncase 1:break;}" "Right (JSSwitch (JSExpression [JSIdentifier \"x\"]) JSBlock ([JSCase (JSExpression [JSDecimal \"0\"]) ([]),JSCase (JSExpression [JSDecimal \"1\"]) ([JSBreak [] JSLiteral \";\"])]))") , testCase "Switch4" (testStmt "switch (x) {default:break;}" "Right (JSSwitch (JSExpression [JSIdentifier \"x\"]) JSBlock ([JSLiteral \"\",JSDefault ([JSBreak [] JSLiteral \";\"]),JSLiteral \"\"]))") , testCase "Switch5" (testStmt "switch (x) {default:\ncase 1:break;}" "Right (JSSwitch (JSExpression [JSIdentifier \"x\"]) JSBlock ([JSLiteral \"\",JSDefault ([]),JSCase (JSExpression [JSDecimal \"1\"]) ([JSBreak [] JSLiteral \";\"])]))") , testCase "Throw1" (testStmt "throw 1" "Right (JSThrow (JSExpression [JSDecimal \"1\"]))") , testCase "Try1" (testStmt "try{}catch(a){}" "Right (JSTry (JSBlock ([])) [JSCatch (JSIdentifier \"a\") [] (JSBlock ([]))])") , testCase "Try2" (testStmt "try{}finally{}" "Right (JSTry (JSBlock ([])) [JSFinally (JSBlock ([]))])") , testCase "Try3" (testStmt "try{}catch(a){}finally{}" "Right (JSTry (JSBlock ([])) [JSCatch (JSIdentifier \"a\") [] (JSBlock ([])),JSFinally (JSBlock ([]))])") , testCase "Try4" (testStmt "try{}catch(a){}catch(b){}finally{}" "Right (JSTry (JSBlock ([])) [JSCatch (JSIdentifier \"a\") [] (JSBlock ([])),JSCatch (JSIdentifier \"b\") [] (JSBlock ([])),JSFinally (JSBlock ([]))])") , testCase "Try5" (testStmt "try{}catch(a){}catch(b){}" "Right (JSTry (JSBlock ([])) [JSCatch (JSIdentifier \"a\") [] (JSBlock ([])),JSCatch (JSIdentifier \"b\") [] (JSBlock ([]))])") , testCase "Try6" (testStmt "try{}catch(a if true){}catch(b){}" "Right (JSTry (JSBlock ([])) [JSCatch (JSIdentifier \"a\") [JSLiteral \"if\",JSLiteral \"true\"] (JSBlock ([])),JSCatch (JSIdentifier \"b\") [] (JSBlock ([]))])") , testCase "Function1" (testProg "function a(){}" "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"a\") [] (JSBlock ([])),JSLiteral \"\"])") , testCase "Function2" (testProg "function a(b,c){}" "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"a\") [JSIdentifier \"b\",JSLiteral \",\",JSIdentifier \"c\"] (JSBlock ([])),JSLiteral \"\"])") , testCase "Comment1" (testProg "//blah\nx=1;//foo\na" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSExpression [JSIdentifier \"a\"],JSLiteral \"\"])") , testCase "Comment2" (testProg "/*x=1\ny=2\n*/z=2;//foo\na" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"z\",JSOperator JSLiteral \"=\",JSDecimal \"2\"],JSLiteral \";\",JSExpression [JSIdentifier \"a\"],JSLiteral \"\"])") , testCase "min_100_animals1" (testProg "function Animal(name){if(!name)throw new Error('Must specify an animal name');this.name=name};Animal.prototype.toString=function(){return this.name};o=new Animal(\"bob\");o.toString()==\"bob\"" "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"Animal\") [JSIdentifier \"name\"] (JSBlock ([JSIf (JSExpression [JSUnary \"!\",JSIdentifier \"name\"]) ([JSThrow (JSExpression [JSLiteral \"new\",JSIdentifier \"Error\",JSArguments [JSStringLiteral '\\'' \"Must specify an animal name\"]]),JSLiteral \";\"]) ([]),JSExpression [JSMemberDot [JSLiteral \"this\"] (JSIdentifier \"name\"),JSOperator JSLiteral \"=\",JSIdentifier \"name\"]])),JSLiteral \";\",JSExpression [JSMemberDot [JSMemberDot [JSIdentifier \"Animal\"] (JSIdentifier \"prototype\")] (JSIdentifier \"toString\"),JSOperator JSLiteral \"=\",JSFunctionExpression [] [] (JSBlock ([JSReturn [JSExpression [JSMemberDot [JSLiteral \"this\"] (JSIdentifier \"name\")]] JSLiteral \"\"]))],JSLiteral \";\",JSExpression [JSIdentifier \"o\",JSOperator JSLiteral \"=\",JSLiteral \"new\",JSIdentifier \"Animal\",JSArguments [JSStringLiteral '\"' \"bob\"]],JSLiteral \";\",JSExpression [JSExpressionBinary \"==\" [JSMemberDot [JSIdentifier \"o\"] (JSIdentifier \"toString\"),JSArguments []] [JSStringLiteral '\"' \"bob\"]],JSLiteral \"\"])") , testCase "min_100_animals2" (testProg "Animal=function(){return this.name};" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"Animal\",JSOperator JSLiteral \"=\",JSFunctionExpression [] [] (JSBlock ([JSReturn [JSExpression [JSMemberDot [JSLiteral \"this\"] (JSIdentifier \"name\")]] JSLiteral \"\"]))],JSLiteral \";\",JSLiteral \"\"])") , testCase "min_100_animals3" (testProg "if(a)x=1;y=2" "Right (JSSourceElementsTop [JSIf (JSExpression [JSIdentifier \"a\"]) ([JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\"]) ([]),JSExpression [JSIdentifier \"y\",JSOperator JSLiteral \"=\",JSDecimal \"2\"],JSLiteral \"\"])") , testCase "min_100_animals4" (testProg "if(a)x=a()y=2" "Right (JSSourceElementsTop [JSIf (JSExpression [JSIdentifier \"a\"]) ([JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSIdentifier \"a\",JSArguments []]]) ([]),JSExpression [JSIdentifier \"y\",JSOperator JSLiteral \"=\",JSDecimal \"2\"],JSLiteral \"\"])") , testCase "05_regex" (testProg "newlines=spaces.match(/\\n/g)" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"newlines\",JSOperator JSLiteral \"=\",JSMemberDot [JSIdentifier \"spaces\"] (JSIdentifier \"match\"),JSArguments [JSRegEx \"/\\\\n/g\"]],JSLiteral \"\"])") , testCase "05_regex2" (testProg "x=/\\n/g" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSRegEx \"/\\\\n/g\"],JSLiteral \"\"])") , testCase "05_regex3" (testProg "x=i(/[?|^&(){}\\[\\]+\\-*\\/\\.]/g,\"\\\\$&\")" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSIdentifier \"i\",JSArguments [JSRegEx \"/[?|^&(){}\\\\[\\\\]+\\\\-*\\\\/\\\\.]/g\",JSLiteral \",\",JSStringLiteral '\"' \"\\\\\\\\$&\"]],JSLiteral \"\"])") , testCase "05_regex4" (testProg "x=i(/^$/g,\"\\\\$&\")" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSIdentifier \"i\",JSArguments [JSRegEx \"/^$/g\",JSLiteral \",\",JSStringLiteral '\"' \"\\\\\\\\$&\"]],JSLiteral \"\"])") , testCase "05_regex5" (testProg "if(/^[a-z]/.test(t)){consts+=t.toUpperCase();keywords[t]=i}else consts+=(/^\\W/.test(t)?opTypeNames[t]:t);" "Right (JSSourceElementsTop [JSIf (JSExpression [JSMemberDot [JSRegEx \"/^[a-z]/\"] (JSIdentifier \"test\"),JSArguments [JSIdentifier \"t\"]]) ([JSBlock ([JSExpression [JSIdentifier \"consts\",JSOperator JSLiteral \"+=\",JSMemberDot [JSIdentifier \"t\"] (JSIdentifier \"toUpperCase\"),JSArguments []],JSLiteral \";\",JSExpression [JSMemberSquare [JSIdentifier \"keywords\"] (JSExpression [JSIdentifier \"t\"]),JSOperator JSLiteral \"=\",JSIdentifier \"i\"]])]) ([JSLiteral \"else\",JSExpression [JSIdentifier \"consts\",JSOperator JSLiteral \"+=\",JSExpressionParen (JSExpression [JSExpressionTernary [JSMemberDot [JSRegEx \"/^\\\\W/\"] (JSIdentifier \"test\"),JSArguments [JSIdentifier \"t\"]] [JSMemberSquare [JSIdentifier \"opTypeNames\"] (JSExpression [JSIdentifier \"t\"])] [JSIdentifier \"t\"]])]]),JSLiteral \";\",JSLiteral \"\"])") , testCase "if_semi" (testProg "if(x);x=1" "Right (JSSourceElementsTop [JSIf (JSExpression [JSIdentifier \"x\"]) ([JSLiteral \";\"]) ([]),JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \"\"])") , testCase "67_bob" (testProg "(match = /^\"(?:\\\\.|[^\"])*\"|^'(?:[^']|\\\\.)*'/(input))" "Right (JSSourceElementsTop [JSExpression [JSExpressionParen (JSExpression [JSIdentifier \"match\",JSOperator JSLiteral \"=\",JSRegEx \"/^\\\"(?:\\\\\\\\.|[^\\\"])*\\\"|^'(?:[^']|\\\\\\\\.)*'/\",JSArguments [JSIdentifier \"input\"]])],JSLiteral \"\"])") , testCase "122_jsexec" (testProg "v = getValue(execute(n[0], x)) in getValue(execute(n[1], x));" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"v\",JSOperator JSLiteral \"=\",JSExpressionBinary \" in \" [JSIdentifier \"getValue\",JSArguments [JSIdentifier \"execute\",JSArguments [JSMemberSquare [JSIdentifier \"n\"] (JSExpression [JSDecimal \"0\"]),JSLiteral \",\",JSIdentifier \"x\"]]] [JSIdentifier \"getValue\",JSArguments [JSIdentifier \"execute\",JSArguments [JSMemberSquare [JSIdentifier \"n\"] (JSExpression [JSDecimal \"1\"]),JSLiteral \",\",JSIdentifier \"x\"]]]],JSLiteral \";\",JSLiteral \"\"])") , testCase "bug1a" (testProg "/* */\nfunction f() {\n/* */\n}\n" "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"f\") [] (JSBlock ([])),JSLiteral \"\"])") , testCase "bug1b" (testProg "/* **/\nfunction f() {\n/* */\n}\n" "Right (JSSourceElementsTop [JSFunction (JSIdentifier \"f\") [] (JSBlock ([])),JSLiteral \"\"])") , testCase "unicode1-ws" (testProg "a \f\v\t\r\n=\x00a0\x1680\x180e\x2000\x2001\x2002\x2003\x2004\x2005\x2006\x2007\x2008\x2009\x200a\x2028\x2029\x202f\x205f\x3000\&1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"a\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"])") , testCase "unicode2-lt" (testProg "//comment\x000Ax=1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"])") , testCase "unicode3-lt" (testProg "//comment\x000Dx=1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"])") , testCase "unicode4-lt" (testProg "//comment\x2028x=1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"])") , testCase "unicode5-lt" (testProg "//comment\x2029x=1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"])") , testCase "unicode2" (testProg "àáâãäå = 1;" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"\\224\\225\\226\\227\\228\\229\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"])") , testCase "unicode3" (testProg "$aà = 1;_b=2;\0065a=2" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"$a\\224\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSExpression [JSIdentifier \"_b\",JSOperator JSLiteral \"=\",JSDecimal \"2\"],JSLiteral \";\",JSExpression [JSIdentifier \"Aa\",JSOperator JSLiteral \"=\",JSDecimal \"2\"],JSLiteral \"\"])") , testCase "unicode4" (testProg "x=\"àáâãäå\";y='\3012a\0068'" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSStringLiteral '\"' \"\\224\\225\\226\\227\\228\\229\"],JSLiteral \";\",JSExpression [JSIdentifier \"y\",JSOperator JSLiteral \"=\",JSStringLiteral '\\'' \"\\3012aD\"],JSLiteral \"\"])") , testCase "unicode5f" (testFileUtf8 "./test/Unicode.js" "JSSourceElementsTop [JSExpression [JSIdentifier \"\\224\\225\\226\\227\\228\\229\",JSOperator JSLiteral \"=\",JSDecimal \"1\"],JSLiteral \";\",JSLiteral \"\"]") , testCase "bug2.a" (testProg "function() {\nz = function /*z*/(o) {\nreturn r;\n};}" "Right (JSSourceElementsTop [JSExpression [JSFunctionExpression [] [] (JSBlock ([JSExpression [JSIdentifier \"z\",JSOperator JSLiteral \"=\",JSFunctionExpression [] [JSIdentifier \"o\"] (JSBlock ([JSReturn [JSExpression [JSIdentifier \"r\"]] JSLiteral \";\"]))],JSLiteral \";\"]))],JSLiteral \"\"])") , testCase "bug2.b" (testProg "function() {\nz = function z(o) {\nreturn r;\n};}" "Right (JSSourceElementsTop [JSExpression [JSFunctionExpression [] [] (JSBlock ([JSExpression [JSIdentifier \"z\",JSOperator JSLiteral \"=\",JSFunctionExpression [JSIdentifier \"z\"] [JSIdentifier \"o\"] (JSBlock ([JSReturn [JSExpression [JSIdentifier \"r\"]] JSLiteral \";\"]))],JSLiteral \";\"]))],JSLiteral \"\"])") -- https://github.com/alanz/hjsmin/issues/#issue/3 , testCase "bug3" (testProg "var myLatlng = new google.maps.LatLng(56.8379100, 60.5806664);" "Right (JSSourceElementsTop [JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"myLatlng\") [JSLiteral \"=\",JSLiteral \"new\",JSMemberDot [JSMemberDot [JSIdentifier \"google\"] (JSIdentifier \"maps\")] (JSIdentifier \"LatLng\"),JSArguments [JSDecimal \"56.8379100\",JSLiteral \",\",JSDecimal \"60.5806664\"]]],JSLiteral \"\"])") -- https://github.com/alanz/hjsmin/issues/#issue/4 , testCase "bug4" (testProg "/* * geolocation. пытаемся определить свое местоположение * если не получается то используем defaultLocation * @Param {object} map экземпляр карты * @Param {object LatLng} defaultLocation Координаты центра по умолчанию * @Param {function} callbackAfterLocation Фу-ия которая вызывается после * геолокации. Т.к запрос геолокации асинхронен */x" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\"],JSLiteral \"\"])") , testCase "02_sm.js" (testProg "{zero}\none1;two\n{three\nfour;five;\n{\nsix;{seven;}\n}\n}" "Right (JSSourceElementsTop [JSBlock ([JSExpression [JSIdentifier \"zero\"]]),JSExpression [JSIdentifier \"one1\"],JSLiteral \";\",JSExpression [JSIdentifier \"two\"],JSBlock ([JSExpression [JSIdentifier \"three\"],JSExpression [JSIdentifier \"four\"],JSLiteral \";\",JSExpression [JSIdentifier \"five\"],JSLiteral \";\",JSBlock ([JSExpression [JSIdentifier \"six\"],JSLiteral \";\",JSBlock ([JSExpression [JSIdentifier \"seven\"],JSLiteral \";\"])])]),JSLiteral \"\"])") , testCase "02_sm.js.2" (testProg "{zero}\nget;two\n{three\nfour;set;\n{\nsix;{seven;}\n}\n}" "Right (JSSourceElementsTop [JSBlock ([JSExpression [JSIdentifier \"zero\"]]),JSExpression [JSIdentifier \"get\"],JSLiteral \";\",JSExpression [JSIdentifier \"two\"],JSBlock ([JSExpression [JSIdentifier \"three\"],JSExpression [JSIdentifier \"four\"],JSLiteral \";\",JSExpression [JSIdentifier \"set\"],JSLiteral \";\",JSBlock ([JSExpression [JSIdentifier \"six\"],JSLiteral \";\",JSBlock ([JSExpression [JSIdentifier \"seven\"],JSLiteral \";\"])])]),JSLiteral \"\"])") , testCase "loc1" (testProgUn "x = 1\n y=2;" "Right (NN (JSSourceElementsTop [NN (JSExpression [NT (JSIdentifier \"x\") (TokenPn 0 1 1) [NoComment],NN (JSOperator (NT (JSLiteral \"=\") (TokenPn 2 1 3) [WhiteSpace (TokenPn 1 1 2) \" \"])),NT (JSDecimal \"1\") (TokenPn 4 1 5) [WhiteSpace (TokenPn 3 1 4) \" \"]]),NN (JSExpression [NT (JSIdentifier \"y\") (TokenPn 8 2 3) [WhiteSpace (TokenPn 5 1 6) \"\\n \"],NN (JSOperator (NT (JSLiteral \"=\") (TokenPn 9 2 4) [NoComment])),NT (JSDecimal \"2\") (TokenPn 10 2 5) [NoComment]]),NT (JSLiteral \";\") (TokenPn 11 2 6) [NoComment],NT (JSLiteral \"\") (TokenPn 0 0 0) [NoComment]]))") -- https://github.com/alanz/language-javascript/issues/2 , testCase "issue2" (testProg "var img = document.createElement('img');\nimg.src = \"mylogo.jpg\";\n$(img).click(function() {\n alert('clicked!');\n});" "Right (JSSourceElementsTop [JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"img\") [JSLiteral \"=\",JSMemberDot [JSIdentifier \"document\"] (JSIdentifier \"createElement\"),JSArguments [JSStringLiteral '\\'' \"img\"]]],JSExpression [JSMemberDot [JSIdentifier \"img\"] (JSIdentifier \"src\"),JSOperator JSLiteral \"=\",JSStringLiteral '\"' \"mylogo.jpg\"],JSLiteral \";\",JSExpression [JSIdentifier \"$\",JSArguments [JSIdentifier \"img\"],JSCallExpression \".\" [JSIdentifier \"click\"],JSCallExpression \"()\" [JSArguments [JSFunctionExpression [] [] (JSBlock ([JSExpression [JSIdentifier \"alert\",JSArguments [JSStringLiteral '\\'' \"clicked!\"]],JSLiteral \";\"]))]]],JSLiteral \";\",JSLiteral \"\"])") -- Working in ECMASCRIPT 5.1 changes , testCase "lineTerminatorInString1" (testProg "x='abc\\\ndef';" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSStringLiteral '\\'' \"abc\\\\\\ndef\"],JSLiteral \";\",JSLiteral \"\"])") , testCase "lineTerminatorInString2" (testProg "x=\"abc\\\ndef\";" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSStringLiteral '\"' \"abc\\\\\\ndef\"],JSLiteral \";\",JSLiteral \"\"])") , testCase "lineTerminatorInString3" (testProg "x=\"abc\\\rdef\";" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSStringLiteral '\"' \"abc\\\\\\rdef\"],JSLiteral \";\",JSLiteral \"\"])") , testCase "lineTerminatorInString4" (testProg "x=\"abc\\\x2028 def\";" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSStringLiteral '\"' \"abc\\\\\\8232 def\"],JSLiteral \";\",JSLiteral \"\"])") , testCase "lineTerminatorInString5" (testProg "x=\"abc\\\x2029 def\";" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSStringLiteral '\"' \"abc\\\\\\8233 def\"],JSLiteral \";\",JSLiteral \"\"])") , testCase "lineTerminatorInString6" (testProg "x=\"abc\\\r\ndef\";" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSStringLiteral '\"' \"abc\\\\\\r\\ndef\"],JSLiteral \";\",JSLiteral \"\"])") -- https://github.com/alanz/language-javascript/issues/4 , testCase "issue4ok" (testProg "var k = {\ny: somename\n}" "Right (JSSourceElementsTop [JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"k\") [JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"y\") [JSIdentifier \"somename\"]]]],JSLiteral \"\"])") , testCase "issue4bug1" (testProg "var k = {\ny: code\n}" "Right (JSSourceElementsTop [JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"k\") [JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"y\") [JSIdentifier \"code\"]]]],JSLiteral \"\"])") , testCase "issue4bug2" (testProg "var k = {\ny: mode\n}" "Right (JSSourceElementsTop [JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"k\") [JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"y\") [JSIdentifier \"mode\"]]]],JSLiteral \"\"])") -- https://github.com/alanz/language-javascript/issues/5 , testCase "issue5bug1" (testProg "x = { y: 1e8 }" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"y\") [JSDecimal \"1e8\"]]],JSLiteral \"\"])") , testCase "issue5ok2" (testProg "{ y: 1e8 }" "Right (JSSourceElementsTop [JSBlock ([JSLabelled (JSIdentifier \"y\") (JSExpression [JSDecimal \"1e8\"])]),JSLiteral \"\"])") , testCase "issue5ok3" (testProg "{ y: 18 }" "Right (JSSourceElementsTop [JSBlock ([JSLabelled (JSIdentifier \"y\") (JSExpression [JSDecimal \"18\"])]),JSLiteral \"\"])") , testCase "issue5ok4" (testProg "x = { y: 18 }" "Right (JSSourceElementsTop [JSExpression [JSIdentifier \"x\",JSOperator JSLiteral \"=\",JSObjectLiteral [JSPropertyNameandValue (JSIdentifier \"y\") [JSDecimal \"18\"]]],JSLiteral \"\"])") -- https://github.com/alanz/language-javascript/issues/14 , testCase "issue14" (testProg "var z = x[i] / y;" "Right (JSSourceElementsTop [JSVariables JSLiteral \"var\" [JSVarDecl (JSIdentifier \"z\") [JSLiteral \"=\",JSExpressionBinary \"/\" [JSMemberSquare [JSIdentifier \"x\"] (JSExpression [JSIdentifier \"i\"])] [JSIdentifier \"y\"]]],JSLiteral \"\"])") , testCase "AutoSemiBreak" (testProg "if(true)break \nfoo();" "Right (JSSourceElementsTop [JSIf (JSExpression [JSLiteral \"true\"]) ([JSBreak [] JSLiteral \"\"]) ([]),JSExpression [JSIdentifier \"foo\",JSArguments []],JSLiteral \";\",JSLiteral \"\"])") , testCase "AutoSemiContinue" (testProg "if(true)continue \nfoo();" "Right (JSSourceElementsTop [JSIf (JSExpression [JSLiteral \"true\"]) ([JSContinue [] JSLiteral \"\"]) ([]),JSExpression [JSIdentifier \"foo\",JSArguments []],JSLiteral \";\",JSLiteral \"\"])") , testCase "AutoSemiReturn" (testProg "if(true)break \nfoo();" "Right (JSSourceElementsTop [JSIf (JSExpression [JSLiteral \"true\"]) ([JSBreak [] JSLiteral \"\"]) ([]),JSExpression [JSIdentifier \"foo\",JSArguments []],JSLiteral \";\",JSLiteral \"\"])") , testCase "BreakBlock" (testProg "{break}" "Right (JSSourceElementsTop [JSBlock ([JSBreak [] JSLiteral \"\"]),JSLiteral \"\"])") , testCase "ContinueBlock" (testProg "{continue}" "Right (JSSourceElementsTop [JSBlock ([JSContinue [] JSLiteral \"\"]),JSLiteral \"\"])") , testCase "ReturnBlock" (testProg "{return}" "Right (JSSourceElementsTop [JSBlock ([JSReturn [] JSLiteral \"\"]),JSLiteral \"\"])") ] caseHelloWorld :: Assertion caseHelloWorld = "JSSourceElementsTop [JSExpression [JSIdentifier \"Hello\"],JSLiteral \"\"]" @=? showStripped (readJs "Hello") -- --------------------------------------------------------------------- commentSuite :: Test commentSuite = testGroup "Comments" [ testCase "helloWorld" caseHelloWorld , testCase "LiteralNull" (testLiteralC "/*a*/null" "Right (NS (JSLiteral \"null\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"])") , testCase "LiteralFalse" (testLiteralC "/*b*/false" "Right (NS (JSLiteral \"false\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*b*/\"])") , testCase "LiteralTrue" (testLiteralC "true" "Right (NS (JSLiteral \"true\") (TokenPn 0 1 1) [NoComment])") , testCase "LiteralTrue" (testLiteralC "/*c*/true" "Right (NS (JSLiteral \"true\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*c*/\"])") , testCase "LiteralHexInteger" (testLiteralC "/*d*/0x1234fF" "Right (NS (JSHexInteger \"0x1234fF\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*d*/\"])") , testCase "LiteralDecimal" (testLiteralC "/*e*/1.0e4" "Right (NS (JSDecimal \"1.0e4\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*e*/\"])") , testCase "LiteralOctal" (testLiteralC "/*x*/011" "Right (NS (JSOctal \"011\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*x*/\"])") , testCase "LiteralString1" (testLiteralC "/*f*/\"hello\\nworld\"" "Right (NS (JSStringLiteral '\"' \"hello\\\\nworld\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*f*/\"])") , testCase "LiteralString2" (testLiteralC "/*g*/'hello\\nworld'" "Right (NS (JSStringLiteral '\\'' \"hello\\\\nworld\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*g*/\"])") , testCase "LiteralThis" (testPEC "/*h*/this" "Right (NS (JSLiteral \"this\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*h*/\"])") , testCase "LiteralRegex1" (testPEC "/*i*//blah/" "Right (NS (JSRegEx \"/blah/\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*i*/\"])") , testCase "Identifier2" (testPEC "//j\nthis_" "Right (NS (JSIdentifier \"this_\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"//j\"])") , testCase "ArrayLiteral1" (testPEC "/*a*/[/*b*/]" "Right (NS (JSArrayLiteral []) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 6 1 7) \"/*b*/\"])") , testCase "ArrayLiteral2" (testPEC "/*a*/[/*b*/,/*c*/]" "Right (NS (JSArrayLiteral [NS (JSElision []) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 12 1 13) \"/*c*/\"])") , testCase "ArrayLiteral3" (testPEC "/*a*/[/*b*/,/*c*/,/*d*/]" "Right (NS (JSArrayLiteral [NS (JSElision []) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"],NS (JSElision []) (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 18 1 19) \"/*d*/\"])") , testCase "ArrayLiteral4" (testPEC "/*a*/[/*b/*,/*c*/,/*d*/x/*e*/]" "Right (NS (JSArrayLiteral [NS (JSElision []) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b/*,/*c*/\"],NS (JSIdentifier \"x\") (TokenPn 18 1 19) [CommentA (TokenPn 18 1 19) \"/*d*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 24 1 25) \"/*e*/\"])") , testCase "ArrayLiteral5" (testPEC "/*a*/[/*b*/,/*c*/,/*d*/x/*e*/]" "Right (NS (JSArrayLiteral [NS (JSElision []) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"],NS (JSElision []) (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"],NS (JSIdentifier \"x\") (TokenPn 18 1 19) [CommentA (TokenPn 18 1 19) \"/*d*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 24 1 25) \"/*e*/\"])") , testCase "ArrayLiteral6" (testPEC "/*a*/[/*b*/,/*c*/x/*d*/,/*e*/,/*f*/x/*g*/]" "Right (NS (JSArrayLiteral [NS (JSElision []) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"],NS (JSIdentifier \"x\") (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"],NS (JSElision []) (TokenPn 18 1 19) [CommentA (TokenPn 18 1 19) \"/*d*/\"],NS (JSElision []) (TokenPn 24 1 25) [CommentA (TokenPn 24 1 25) \"/*e*/\"],NS (JSIdentifier \"x\") (TokenPn 30 1 31) [CommentA (TokenPn 30 1 31) \"/*f*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 36 1 37) \"/*g*/\"])") , testCase "ArrayLiteral7" (testPEC "/*a*/[/*b*/x/*c*/]" "Right (NS (JSArrayLiteral [NS (JSIdentifier \"x\") (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 12 1 13) \"/*c*/\"])") , testCase "ArrayLiteral8" (testPEC "/*a*/[/*b*/x/*c*/,/*d*/]" "Right (NS (JSArrayLiteral [NS (JSIdentifier \"x\") (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"],NS (JSLiteral \",\") (TokenPn 17 1 18) [CommentA (TokenPn 12 1 13) \"/*c*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 18 1 19) \"/*d*/\"])") , testCase "ObjectLiteral1" (testPEC "/*a*/{/*b*/}" "Right (NS (JSObjectLiteral []) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 6 1 7) \"/*b*/\"])") , testCase "ObjectLiteral2" (testPEC "/*a*/{/*b*/x/*c*/:/*d*/1/*e*/}" "Right (NS (JSObjectLiteral [NS (JSPropertyNameandValue (NS (JSIdentifier \"x\") (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]) [NS (JSDecimal \"1\") (TokenPn 18 1 19) [CommentA (TokenPn 18 1 19) \"/*d*/\"]]) (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 24 1 25) \"/*e*/\"])") , testCase "ObjectLiteral3" (testPEC "/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/y/*g*/:/*h*/2/*i*/}" "Right (NS (JSObjectLiteral [NS (JSPropertyNameandValue (NS (JSIdentifier \"x\") (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]) [NS (JSDecimal \"1\") (TokenPn 18 1 19) [CommentA (TokenPn 18 1 19) \"/*d*/\"]]) (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"],NS (JSPropertyNameandValue (NS (JSIdentifier \"y\") (TokenPn 30 1 31) [CommentA (TokenPn 30 1 31) \"/*f*/\"]) [NS (JSDecimal \"2\") (TokenPn 42 1 43) [CommentA (TokenPn 42 1 43) \"/*h*/\"]]) (TokenPn 36 1 37) [CommentA (TokenPn 24 1 25) \"/*e*/\",CommentA (TokenPn 36 1 37) \"/*g*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 48 1 49) \"/*i*/\"])") , testCase "ObjectLiteral5" (testPEC "/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/}" "Right (NS (JSObjectLiteral [NS (JSPropertyNameandValue (NS (JSIdentifier \"x\") (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]) [NS (JSDecimal \"1\") (TokenPn 18 1 19) [CommentA (TokenPn 18 1 19) \"/*d*/\"]]) (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"],NS (JSLiteral \",\") (TokenPn 29 1 30) [CommentA (TokenPn 24 1 25) \"/*e*/\"]]) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 30 1 31) \"/*f*/\"])") -- Edition 5 extensions , testCase "ObjectLiteral7" (testProgC "/*a*/x/*b*/=/*c*/{/*d*/get/*e*/ foo/*f*/(/*g*/)/*h*/ {/*i*/return/*j*/ 1/*k*/}/*l*/,/*m*/set/*n*/ foo/*o*/(/*p*/a/*q*/) /*r*/{/*s*/x/*t*/=/*u*/a/*v*/}/*w*/}" "Right (NS (JSSourceElementsTop [NS (JSExpression [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"],NS (JSOperator \"=\") (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"],NS (JSObjectLiteral [NS (JSPropertyAccessor \"get\" (NS (JSIdentifier \"foo\") (TokenPn 26 1 27) [CommentA (TokenPn 26 1 27) \"/*e*/\"]) [] (NS (JSFunctionBody [NS (JSSourceElements [NS (JSReturn [NS (JSExpression [NS (JSDecimal \"1\") (TokenPn 65 1 66) [CommentA (TokenPn 65 1 66) \"/*j*/\"]]) (TokenPn 65 1 66) [],NS (JSLiteral \"\") (TokenPn 0 0 0) []]) (TokenPn 54 1 55) [CommentA (TokenPn 54 1 55) \"/*i*/\"]]) (TokenPn 54 1 55) []]) (TokenPn 54 1 55) [])) (TokenPn 18 1 19) [CommentA (TokenPn 18 1 19) \"/*d*/\",CommentA (TokenPn 35 1 36) \"/*f*/\",CommentA (TokenPn 41 1 42) \"/*g*/\",CommentA (TokenPn 47 1 48) \"/*h*/\",CommentA (TokenPn 72 1 73) \"/*k*/\"],NS (JSPropertyAccessor \"set\" (NS (JSIdentifier \"foo\") (TokenPn 92 1 93) [CommentA (TokenPn 92 1 93) \"/*n*/\"]) [NS (JSIdentifier \"a\") (TokenPn 107 1 108) [CommentA (TokenPn 107 1 108) \"/*p*/\"]] (NS (JSFunctionBody [NS (JSSourceElements [NS (JSExpression [NS (JSIdentifier \"x\") (TokenPn 126 1 127) [CommentA (TokenPn 126 1 127) \"/*s*/\"],NS (JSOperator \"=\") (TokenPn 132 1 133) [CommentA (TokenPn 132 1 133) \"/*t*/\"],NS (JSIdentifier \"a\") (TokenPn 138 1 139) [CommentA (TokenPn 138 1 139) \"/*u*/\"]]) (TokenPn 126 1 127) []]) (TokenPn 126 1 127) []]) (TokenPn 126 1 127) [])) (TokenPn 84 1 85) [CommentA (TokenPn 78 1 79) \"/*l*/\",CommentA (TokenPn 84 1 85) \"/*m*/\",CommentA (TokenPn 101 1 102) \"/*o*/\",CommentA (TokenPn 113 1 114) \"/*q*/\",CommentA (TokenPn 120 1 121) \"/*r*/\",CommentA (TokenPn 144 1 145) \"/*v*/\"]]) (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\",CommentA (TokenPn 150 1 151) \"/*w*/\"]]) (TokenPn 0 1 1) []]) (TokenPn 0 1 1) [])") , testCase "ExpressionParen" (testPEC "/*a*/(/*b*/56/*c*/)" "Right (NS (JSExpressionParen (NS (JSExpression [NS (JSDecimal \"56\") (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])) (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\",CommentA (TokenPn 13 1 14) \"/*c*/\"])") , testCase "Statement1" (testStmtC "/*a*/x" "Right (NS (JSExpression [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]]) (TokenPn 0 1 1) [])") , testCase "Statement2" (testStmtC "/*a*/null" "Right (NS (JSExpression [NS (JSLiteral \"null\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]]) (TokenPn 0 1 1) [])") , testCase "Statement3" (testStmtC "/*a*/true/*b*/?/*c*/1/*d*/:/*e*/2" "Right (NS (JSExpression [NS (JSExpressionTernary [NS (JSLiteral \"true\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSDecimal \"1\") (TokenPn 15 1 16) [CommentA (TokenPn 15 1 16) \"/*c*/\"]] [NS (JSDecimal \"2\") (TokenPn 27 1 28) [CommentA (TokenPn 27 1 28) \"/*e*/\"]]) (TokenPn 9 1 10) [CommentA (TokenPn 9 1 10) \"/*b*/\",CommentA (TokenPn 21 1 22) \"/*d*/\"]]) (TokenPn 9 1 10) [])") , testCase "Statement4" (testStmtC "/*a*/x/*b*/||/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"||\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 13 1 14) [CommentA (TokenPn 13 1 14) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])") , testCase "Statement5" (testStmtC "/*a*/x/*b*/&&/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"&&\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 13 1 14) [CommentA (TokenPn 13 1 14) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])") , testCase "Statement6a" (testStmtC "/*a*/x/*b*/|/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"|\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])") , testCase "Statement6b" (testStmtC "/*a*/x/*b*/^/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"^\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])") , testCase "Statement7" (testStmtC "/*a*/x/*b*/&/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"&\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])") , testCase "Statement8" (testStmtC "/*a*/x/*b*/==/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"==\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 13 1 14) [CommentA (TokenPn 13 1 14) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])") , testCase "Statement9" (testStmtC "/*a*/x/*b*/!=/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"!=\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 13 1 14) [CommentA (TokenPn 13 1 14) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])") , testCase "Statement10" (testStmtC "/*a*/x/*b*/===/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"===\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 14 1 15) [CommentA (TokenPn 14 1 15) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])") , testCase "Statement11" (testStmtC "/*a*/x/*b*/!==/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"!==\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 14 1 15) [CommentA (TokenPn 14 1 15) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])") , testCase "Statement12a" (testStmtC "/*a*/x/*b*//*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \">\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 12 1 13) [CommentA (TokenPn 12 1 13) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])") , testCase "Statement12c" (testStmtC "/*a*/x/*b*/<=/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \"<=\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 13 1 14) [CommentA (TokenPn 13 1 14) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])") , testCase "Statement12d" (testStmtC "/*a*/x/*b*/>=/*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \">=\" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 13 1 14) [CommentA (TokenPn 13 1 14) \"/*c*/\"]]) (TokenPn 6 1 7) [CommentA (TokenPn 6 1 7) \"/*b*/\"]]) (TokenPn 6 1 7) [])") , testCase "Statement12e" (testStmtC "/*a*/x /*b*/instanceof /*c*/y" "Right (NS (JSExpression [NS (JSExpressionBinary \" instanceof \" [NS (JSIdentifier \"x\") (TokenPn 0 1 1) [CommentA (TokenPn 0 1 1) \"/*a*/\"]] [NS (JSIdentifier \"y\") (TokenPn 23 1 24) [CommentA (TokenPn 23 1 24) \"/*c*/\"]]) (TokenPn 7 1 8) [CommentA (TokenPn 7 1 8) \"/*b*/\"]]) (TokenPn 7 1 8) [])") ] -- --------------------------------------------------------------------- commentPrintSuite :: Test commentPrintSuite = testGroup "Comments" [ testCase "Multi-comment" (testRoundTrip "/*a*/\n//foo\nnull") , testCase "LiteralNull" (testRoundTrip "/*a*/null") , testCase "LiteralFalse" (testRoundTrip "/*b*/false") , testCase "LiteralTrue" (testRoundTrip "true") , testCase "LiteralTrue" (testRoundTrip "/*c*/true") , testCase "LiteralHexInteger" (testRoundTrip "/*d*/0x1234fF") , testCase "LiteralDecimal" (testRoundTrip "/*e*/1.0e4") , testCase "LiteralOctal" (testRoundTrip "/*x*/011") , testCase "LiteralString1" (testRoundTrip "/*f*/\"hello\\nworld\"") , testCase "LiteralString2" (testRoundTrip "/*g*/'hello\\nworld'") , testCase "LiteralThis" (testRoundTrip "/*h*/this") , testCase "LiteralRegex1" (testRoundTrip "/*i*//blah/") , testCase "Identifier2" (testRoundTrip "//j\nthis_") , testCase "ArrayLiteral1" (testRoundTrip "/*a*/[/*b*/]") , testCase "ArrayLiteral2" (testRoundTrip "/*a*/[/*b*/,/*c*/]") , testCase "ArrayLiteral3" (testRoundTrip "/*a*/[/*b*/,/*c*/,/*d*/]") , testCase "ArrayLiteral4" (testRoundTrip "/*a*/[/*b/*,/*c*/,/*d*/x/*e*/]") , testCase "ArrayLiteral5" (testRoundTrip "/*a*/[/*b*/,/*c*/,/*d*/x/*e*/]") , testCase "ArrayLiteral6" (testRoundTrip "/*a*/[/*b*/,/*c*/x/*d*/,/*e*/,/*f*/x/*g*/]") , testCase "ArrayLiteral7" (testRoundTrip "/*a*/[/*b*/x/*c*/]") , testCase "ArrayLiteral8" (testRoundTrip "/*a*/[/*b*/x/*c*/,/*d*/]") , testCase "ObjectLiteral1" (testRoundTrip "/*a*/{/*b*/}") , testCase "ObjectLiteral2" (testRoundTrip "/*a*/{/*b*/x/*c*/:/*d*/1/*e*/}") , testCase "ObjectLiteral3" (testRoundTrip "x=/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/y/*g*/:/*h*/2/*i*/}") , testCase "ObjectLiteral3a" (testRoundTrip "x=/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/y/*g*/:/*h*/2/*i*/,/*j*/z/*k*/:/*l*/3/*m*/}") , testCase "ObjectLiteral5" (testRoundTrip "a=/*a*/{/*b*/x/*c*/:/*d*/1/*e*/,/*f*/}") -- Edition 5 extensions , testCase "ObjectLiteral7" (testRoundTrip "/*a*/x/*b*/=/*c*/{/*d*/get/*e*/ foo/*f*/(/*g*/)/*h*/ {/*i*/return/*j*/ 1/*k*/}/*l*/,/*m*/set/*n*/ foo/*o*/(/*p*/a/*q*/) /*r*/{/*s*/x/*t*/=/*u*/a/*v*/}/*w*/}") , testCase "ExpressionParen" (testRoundTrip "/*a*/(/*b*/56/*c*/)") , testCase "Statement1" (testRoundTrip "/*a*/x") , testCase "Statement2" (testRoundTrip "/*a*/null") , testCase "Statement3" (testRoundTrip "/*a*/true/*b*/?/*c*/1/*d*/:/*e*/2") , testCase "Statement4" (testRoundTrip "/*a*/x/*b*/||/*c*/y") , testCase "Statement5" (testRoundTrip "/*a*/x/*b*/&&/*c*/y") , testCase "Statement6a" (testRoundTrip "/*a*/x/*b*/|/*c*/y") , testCase "Statement6b" (testRoundTrip "/*a*/x/*b*/^/*c*/y") , testCase "Statement7" (testRoundTrip "/*a*/x/*b*/&/*c*/y") , testCase "Statement8" (testRoundTrip "/*a*/x/*b*/==/*c*/y") , testCase "Statement9" (testRoundTrip "/*a*/x/*b*/!=/*c*/y") , testCase "Statement10" (testRoundTrip "/*a*/x/*b*/===/*c*/y") , testCase "Statement11" (testRoundTrip "/*a*/x/*b*/!==/*c*/y") , testCase "Statement12a" (testRoundTrip "/*a*/x/*b*//*c*/y") , testCase "Statement12c" (testRoundTrip "/*a*/x/*b*/<=/*c*/y") , testCase "Statement12d" (testRoundTrip "/*a*/x/*b*/>=/*c*/y") , testCase "Statement12e" (testRoundTrip "/*a*/x /*b*/instanceof /*c*/y") , testCase "Statement13" (testRoundTrip "x<>y") , testCase "Statement13" (testRoundTrip "x>>>y") , testCase "Statement14" (testRoundTrip "x+y") , testCase "Statement14" (testRoundTrip "x-y") , testCase "Statement15" (testRoundTrip "x*y") , testCase "Statement16" (testRoundTrip "x/y") , testCase "Statement17" (testRoundTrip "x%y") , testCase "Statement18" (testRoundTrip "delete y") , testCase "Statement19" (testRoundTrip "void y") , testCase "Statement20" (testRoundTrip "typeof y") , testCase "Statement21" (testRoundTrip "++y") , testCase "Statement22" (testRoundTrip "--y") , testCase "Statement23" (testRoundTrip "+y") , testCase "Statement24" (testRoundTrip "-y") , testCase "Statement25" (testRoundTrip "~y") , testCase "Statement26" (testRoundTrip "!y") , testCase "Statement27" (testRoundTrip "y++") , testCase "Statement28" (testRoundTrip "y--") -- Member Expressions , testCase "MemberExpression1a" (testRoundTrip "function(){}") , testCase "MemberExpression1b" (testRoundTrip "function(a){}") , testCase "MemberExpression1c" (testRoundTrip "function(a,b){}") , testCase "MemberExpression1d" (testRoundTrip "x[y]") , testCase "MemberExpression1e" (testRoundTrip "x[y][z]") , testCase "MemberExpression1f" (testRoundTrip "x.y") , testCase "MemberExpression1g" (testRoundTrip "x.y.z") , testCase "MemberExpression1h" (testRoundTrip "new x()") , testCase "NewExpression1" (testRoundTrip "new x.y") , testCase "CallExpression1" (testRoundTrip "x()") , testCase "CallExpression2" (testRoundTrip "x()()") , testCase "CallExpression3" (testRoundTrip "x()[4]") , testCase "CallExpression4" (testRoundTrip "x().x") , testCase "CallExpression5" (testRoundTrip "x(a,b=2).x") , testCase "AssignExpression1" (testRoundTrip "x=1") , testCase "AssignExpression1" (testRoundTrip "x*=1") , testCase "AssignExpression1" (testRoundTrip "x/=1") , testCase "AssignExpression1" (testRoundTrip "x%=1") , testCase "AssignExpression1" (testRoundTrip "x+=1") , testCase "AssignExpression1" (testRoundTrip "x-=1") , testCase "AssignExpression1" (testRoundTrip "x<<=1") , testCase "AssignExpression1" (testRoundTrip "x>>=1") , testCase "AssignExpression1" (testRoundTrip "x>>>=1") , testCase "AssignExpression1" (testRoundTrip "x&=1") , testCase "AssignExpression1" (testRoundTrip "x^=1") , testCase "AssignExpression1" (testRoundTrip "x|=1") , testCase "Block1" (testRoundTrip "{}") , testCase "Block2" (testRoundTrip "{x=1}") , testCase "Block3" (testRoundTrip "{x=1;y=2}") , testCase "Block4" (testRoundTrip "{{}}") , testCase "Block5" (testRoundTrip "{{{}}}") , testCase "If1" (testRoundTrip "if (1) {}") , testCase "IfElse1" (testRoundTrip "if (1) {} else {}") , testCase "IfElse2" (testRoundTrip "if (1) x=1; else {}") , testCase "DoWhile1" (testRoundTrip "do {x=1} while (true);") , testCase "While1" (testRoundTrip "while(true);") , testCase "For1" (testRoundTrip "for(;;);") , testCase "For2" (testRoundTrip "for(x=1;x<10;x++);") , testCase "ForVar1" (testRoundTrip "for(var x;;);") , testCase "ForVar2" (testRoundTrip "for(var x=1;;);") , testCase "ForVar2" (testRoundTrip "for(var x;y;z){}") , testCase "ForIn1" (testRoundTrip "for(x in 5){}") , testCase "ForVarIn1" (testRoundTrip "for(var x in 5){}") , testCase "Var1" (testRoundTrip "var x=1;") , testCase "Var2" (testRoundTrip "const x=1,y=2;") , testCase "Continue1" (testRoundTrip "continue;") , testCase "Continue2" (testRoundTrip "continue x;") , testCase "Break1" (testRoundTrip "break;") , testCase "Break2" (testRoundTrip "break x;") , testCase "Return1" (testRoundTrip "return;") , testCase "Return2" (testRoundTrip "return x;") , testCase "With1" (testRoundTrip "with (x) {};") , testCase "Labelled1" (testRoundTrip "abc:x=1") , testCase "Switch1" (testRoundTrip "switch (x) {}") , testCase "Switch2" (testRoundTrip "switch (x) {case 1:break;}") , testCase "Switch3" (testRoundTrip "switch (x) {case 0:\ncase 1:break;}") , testCase "Switch4" (testRoundTrip "switch (x) {default:break;}") , testCase "Switch5" (testRoundTrip "switch (x) {default:\ncase 1:break;}") , testCase "Throw1" (testRoundTrip "throw 1") , testCase "Try1" (testRoundTrip "try{}catch(a){}") , testCase "Try2" (testRoundTrip "try{}finally{}") , testCase "Try3" (testRoundTrip "try{}catch(a){}finally{}") , testCase "Try4" (testRoundTrip "try{}catch(a){}catch(b){}finally{}") , testCase "Try5" (testRoundTrip "try{}catch(a){}catch(b){}") , testCase "Try6" (testRoundTrip "try{}catch(a if true){}catch(b){}") , testCase "Function1" (testRoundTrip "function a(){}") , testCase "Function2" (testRoundTrip "function a(b,c){}") , testCase "Comment1" (testRoundTrip "//blah\nx=1;//foo\na") , testCase "Comment2" (testRoundTrip "/*x=1\ny=2\n*/z=2;//foo\na") , testCase "min_100_animals1" (testRoundTrip "function Animal(name){if(!name)throw new Error('Must specify an animal name');this.name=name};Animal.prototype.toString=function(){return this.name};o=new Animal(\"bob\");o.toString()==\"bob\"") , testCase "min_100_animals2" (testRoundTrip "Animal=function(){return this.name};") , testCase "min_100_animals3" (testRoundTrip "if(a)x=1;y=2") , testCase "min_100_animals4" (testRoundTrip "if(a)x=a()y=2") , testCase "05_regex" (testRoundTrip "newlines=spaces.match(/\\n/g)") , testCase "05_regex2" (testRoundTrip "x=/\\n/g") , testCase "05_regex3" (testRoundTrip "x=i(/[?|^&(){}\\[\\]+\\-*\\/\\.]/g,\"\\\\$&\")") , testCase "05_regex4" (testRoundTrip "x=i(/^$/g,\"\\\\$&\")") , testCase "05_regex5" (testRoundTrip "if(/^[a-z]/.test(t)){consts+=t.toUpperCase();keywords[t]=i}else consts+=(/^\\W/.test(t)?opTypeNames[t]:t);") , testCase "if_semi" (testRoundTrip "if(x);x=1") , testCase "67_bob" (testRoundTrip "(match = /^\"(?:\\\\.|[^\"])*\"|^'(?:[^']|\\\\.)*'/(input))") , testCase "122_jsexec" (testRoundTrip "v = getValue(execute(n[0], x)) in getValue(execute(n[1], x));") , testCase "bug1a" (testRoundTrip "/* */\nfunction f() {\n/* */\n}") , testCase "bug1b" (testRoundTrip "/* **/\nfunction f() {\n/* */\n}") , testCase "unicode1-ws" (testRoundTrip "a \f\v\t\r\n=\x00a0\x1680\x180e\x2000\x2001\x2002\x2003\x2004\x2005\x2006\x2007\x2008\x2009\x200a\x2028\x2029\x202f\x205f\x3000\&1;") , testCase "unicode2-lt" (testRoundTrip "//comment\x000Ax=1;") , testCase "unicode3-lt" (testRoundTrip "//comment\x000Dx=1;") , testCase "unicode4-lt" (testRoundTrip "//comment\x2028x=1;") , testCase "unicode5-lt" (testRoundTrip "//comment\x2029x=1;") , testCase "unicode2" (testRoundTrip "àáâãäå = 1;") , testCase "unicode3" (testRoundTrip "$aà = 1;_b=2;\0065a=2") , testCase "unicode4" (testRoundTrip "x=\"àáâãäå\";y='\3012a\0068'") -- , testCase "unicode5" (testFile "./test/Unicode.js") , testCase "bug2.a" (testRoundTrip "function() {\nz = function /*z*/(o) {\nreturn r;\n};}") , testCase "bug2.b" (testRoundTrip "function() {\nz = function z(o) {\nreturn r;\n};}") -- https://github.com/alanz/hjsmin/issues/#issue/3 , testCase "bug3" (testRoundTrip "var myLatlng = new google.maps.LatLng(56.8379100, 60.5806664);") -- https://github.com/alanz/hjsmin/issues/#issue/4 , testCase "bug4" (testRoundTrip "/* * geolocation. пытаемся определить свое местоположение * если не получается то используем defaultLocation * @Param {object} map экземпляр карты * @Param {object LatLng} defaultLocation Координаты центра по умолчанию * @Param {function} callbackAfterLocation Фу-ия которая вызывается после * геолокации. Т.к запрос геолокации асинхронен */x") , testCase "02_sm.js" (testRoundTrip "{zero}\none1;two\n{three\nfour;five;\n{\nsix;{seven;}\n}\n}") , testCase "02_sm.js.2" (testRoundTrip "{zero}\nget;two\n{three\nfour;set;\n{\nsix;{seven;}\n}\n}") , testCase "loc1" (testRoundTrip "x = 1\n y=2;") -- https://github.com/alanz/language-javascript/issues/2 , testCase "issue2" (testRoundTrip "var img = document.createElement('img');\nimg.src = \"mylogo.jpg\";\n$(img).click(function() {\n alert('clicked!');\n});") -- Working in ECMASCRIPT 5.1 changes , testCase "lineTerminatorInString1" (testRoundTrip "x='abc\\\ndef';") , testCase "lineTerminatorInString2" (testRoundTrip "x=\"abc\\\ndef\";") , testCase "lineTerminatorInString3" (testRoundTrip "x=\"abc\\\rdef\";") , testCase "lineTerminatorInString4" (testRoundTrip "x=\"abc\\\x2028 def\";") , testCase "lineTerminatorInString5" (testRoundTrip "x=\"abc\\\x2029 def\";") , testCase "lineTerminatorInString6" (testRoundTrip "x=\"abc\\\r\ndef\";") -- https://github.com/alanz/language-javascript/issues/4 , testCase "issue4ok" (testRoundTrip "var k = {\ny: somename\n}") , testCase "issue4bug1" (testRoundTrip "var k = {\ny: code\n}") , testCase "issue4bug2" (testRoundTrip "var k = {\ny: mode\n}") -- https://github.com/alanz/language-javascript/issues/5 , testCase "issue5bug1" (testRoundTrip "x = { y: 1e8 }") , testCase "issue5ok2" (testRoundTrip "{ y: 1e8 }") , testCase "issue5ok3" (testRoundTrip "{ y: 18 }") , testCase "issue5ok4" (testRoundTrip "x = { y: 18 }") -- function body , testCase "functionbody" (testRoundTrip "function foo(a,b,c)\n{x=1;}") , testCase "functionexpression" (testRoundTrip "function foo(a,b,c)\n{x=1;}") , testCase "fn1" (testRoundTrip "function foo() { return 5; }") , testCase "fn2" (testRoundTrip "var foo = function() { return 5; }") , testCase "fn3" (testRoundTrip "var foo = function foo() { return 5; }") -- Parse failure in hjsmin , testCase "parsefail" (testRoundTrip "switch(t){case DIV: v = u / v; break;}") -- https://github.com/alanz/language-javascript/issues/14 , testCase "issue14" (testRoundTrip "var z = x[i] / y;") -- https://github.com/alanz/language-javascript/issues/15 , testCase "issue15" (testRoundTrip "x\t=1;") , testCase "comment-only" (testRoundTrip "// comment\n\n") , testCase "empty-src" (testRoundTrip "") ] -- --------------------------------------------------------------------- -- Test utilities testRoundTrip:: String -> Assertion testRoundTrip str = str @=? renderToString (readJs str) testLiteral :: String -> String -> Assertion testLiteral literal expected = expected @=? showStrippedMaybe (parseUsing parseLiteral literal "src") testLiteralC :: String -> String -> Assertion testLiteralC literal expected = expected @=? show (parseUsing parseLiteral literal "src") testPE :: String -> String -> Assertion testPE str expected = expected @=? showStrippedMaybe (parseUsing parsePrimaryExpression str "src") testPEC :: String -> String -> Assertion testPEC str expected = expected @=? show (parseUsing parsePrimaryExpression str "src") testStmt :: String -> String -> Assertion testStmt str expected = expected @=? showStrippedMaybe (parseUsing parseStatement str "src") testStmtC :: String -> String -> Assertion testStmtC str expected = expected @=? show (parseUsing parseStatement str "src") testProg :: String -> String -> Assertion testProg str expected = expected @=? showStrippedMaybe (parseUsing parseProgram str "src") testProgC :: String -> String -> Assertion testProgC str expected = expected @=? show (parseUsing parseProgram str "src") testProgUn :: String -> String -> Assertion testProgUn str expected = expected @=? show (parseUsing parseProgram str "src") testFile :: FilePath -> String -> IO () testFile fileName expected = do res <- parseFile fileName expected @=? showStripped res testFileUtf8 :: FilePath -> String -> IO () testFileUtf8 fileName expected = do res <- parseFileUtf8 fileName expected @=? showStripped res testLexer :: String -> String -> Assertion testLexer str expected = expected @=? either id stringify (alexTestTokeniser str) stringify :: [Token] -> String stringify xs = "[" ++ intercalate "," (map (takeWhile (/= ' ') . show) xs) ++ "]" language-javascript-0.5.14.2/LICENSE0000644000000000000000000000276512557503314015102 0ustar0000000000000000Copyright (c)2010, Alan Zimmerman All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Alan Zimmerman nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. language-javascript-0.5.14.2/test/0000755000000000000000000000000012557503314015042 5ustar0000000000000000language-javascript-0.5.14.2/test/Unicode.js0000644000000000000000000000005712557503314016770 0ustar0000000000000000// -*- coding: utf-8 -*- àáâãäå = 1; language-javascript-0.5.14.2/test/unicode.txt0000644000000000000000000000313212557503314017230 0ustar0000000000000000-*- coding: utf-8; mode: xub -*- ¢ € ₠ £ ¥ ¤ ° © ® ™ § ¶ † ‡ ※ •◦ ‣ ✓ ●■◆ ○□◇ ★☆ ♠♣♥♦ ♤♧♡♢ “” ‘’ ¿¡ «» ‹› ¶§ª - ‐ ‑ ‒ – — ― … àáâãäåæç èéêë ìíîï ðñòóôõö øùúûüýþÿ ÀÁÂÃÄÅ Ç ÈÉÊË ÌÍÎÏ ÐÑ ÒÓÔÕÖ ØÙÚÛÜÝÞß Æ ᴁ ᴂ ᴈ ΑΒΓΔ ΕΖΗΘ ΙΚΛΜ ΝΞΟΠ ΡΣΤΥ ΦΧΨΩ αβγδ εζηθ ικλμ νξοπ ρςτυ φχψω ⌈⌉ ⌊⌋ ∏ ∑ ∫ ×÷ ⊕ ⊖ ⊗ ⊘ ⊙ ∙ ∘ ′ ″ ‴ ∼ ∂ √ ≔ × ⁱ ⁰ ¹ ² ³ ₀ ₁ ₂ π ∞ ± ∎ ∀¬∧∨∃⊦∵∴∅∈∉⊂⊃⊆⊇⊄⋂⋃ ≠≤≥≮≯≫≪≈≡ ℕℤℚℝℂ ←→↑↓ ↔ ↖↗↙↘ ⇐⇒⇑⇓ ⇔⇗ ⇦⇨⇧⇩ ↞↠↟↡ ↺↻ ☞☜☝☟ λ ƒ Ɱ ⌘ ⌥ ‸ ⇧ ⌤ ↑ ↓ → ← ⇞ ⇟ ↖ ↘ ⌫ ⌦ ⎋⏏ ↶↷ ◀▶▲▼ ◁▷△▽ ⇄ ⇤⇥ ↹ ↵↩⏎ ⌧ ⌨ ␣ ⌶ ⎗⎘⎙⎚ ⌚⌛ ✂✄ ✉✍ ♩♪♫♬♭♮♯ ➀➁➂➃➄➅➆➇➈➉ 卐卍✝✚✡☥⎈☭☪☮☺☹ ☯☰☱☲☳☴☵☶☷ ☠☢☣☤♲♳⌬♨♿ ☉☼☾☽ ♀♂ ♔♕♖ ♗♘♙ ♚♛ ♜♝♞♟ ❦  、。!,:「」『』〈〉《》〖〗【】〔〕 ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦㄧㄨㄩ 林花謝了春紅 太匆匆, 無奈朝來寒雨 晚來風 胭脂淚 留人醉 幾時重, 自是人生長恨 水長東 http://xahlee.org/emacs/unicode-browser.html http://xahlee.org/Periodic_dosage_dir/t1/20040505_unicode.html language-javascript-0.5.14.2/test/k.js0000644000000000000000000000002312557503314015625 0ustar0000000000000000function f() {} language-javascript-0.5.14.2/src/0000755000000000000000000000000012557503314014652 5ustar0000000000000000language-javascript-0.5.14.2/src/Language/0000755000000000000000000000000012557503314016375 5ustar0000000000000000language-javascript-0.5.14.2/src/Language/JavaScript/0000755000000000000000000000000012557503314020443 5ustar0000000000000000language-javascript-0.5.14.2/src/Language/JavaScript/Parser.hs0000644000000000000000000000124212557503314022232 0ustar0000000000000000module Language.JavaScript.Parser ( PA.parse , PA.readJs , PA.parseFile , PA.parseFileUtf8 , PA.showStripped , PA.showStrippedMaybe , JSNode(..) , Node(..) , CommentAnnotation(..) -- , ParseError(..) -- Source locations , TokenPosn(..) , tokenPosnEmpty -- * Pretty Printing , renderJS , renderToString ) where import Language.JavaScript.Parser.AST import Language.JavaScript.Parser.Token import qualified Language.JavaScript.Parser.Parser as PA import Language.JavaScript.Parser.SrcLocation import Language.JavaScript.Pretty.Printer -- EOF language-javascript-0.5.14.2/src/Language/JavaScript/Parser/0000755000000000000000000000000012557503314021677 5ustar0000000000000000language-javascript-0.5.14.2/src/Language/JavaScript/Parser/ParseError.hs0000644000000000000000000000275112557503314024324 0ustar0000000000000000----------------------------------------------------------------------------- -- | -- Module : Language.JavaScript.ParseError -- Based on language-python version by Bernie Pope -- Copyright : (c) 2009 Bernie Pope -- License : BSD-style -- Stability : experimental -- Portability : ghc -- -- Error values for the lexer and parser. ----------------------------------------------------------------------------- module Language.JavaScript.Parser.ParseError ( ParseError (..) ) where --import Language.JavaScript.Parser.Pretty -- import Control.Monad.Error.Class -- Control.Monad.Trans.Except import Language.JavaScript.Parser.Lexer import Language.JavaScript.Parser.SrcLocation (TokenPosn) -- import Language.JavaScript.Parser.Token (Token) data ParseError = UnexpectedToken Token -- ^ An error from the parser. Token found where it should not be. -- Note: tokens contain their own source span. | UnexpectedChar Char TokenPosn -- ^ An error from the lexer. Character found where it should not be. | StrError String -- ^ A generic error containing a string message. No source location. deriving (Eq, {- Ord,-} Show) class Error a where -- | Creates an exception without a message. -- The default implementation is @'strMsg' \"\"@. noMsg :: a -- | Creates an exception with a message. -- The default implementation of @'strMsg' s@ is 'noMsg'. strMsg :: String -> a instance Error ParseError where noMsg = StrError "" strMsg = StrError language-javascript-0.5.14.2/src/Language/JavaScript/Parser/Parser.hs0000644000000000000000000000501512557503314023470 0ustar0000000000000000module Language.JavaScript.Parser.Parser ( -- * Parsing parse , readJs -- , readJsKeepComments , parseFile , parseFileUtf8 -- * Parsing expressions -- parseExpr , parseUsing , showStripped , showStrippedMaybe ) where import Language.JavaScript.Parser.Grammar5 import Language.JavaScript.Parser.Lexer import qualified Language.JavaScript.Parser.AST as AST import System.IO -- | Parse one compound statement, or a sequence of simple statements. -- Generally used for interactive input, such as from the command line of an interpreter. -- Return comments in addition to the parsed statements. parse :: String -- ^ The input stream (Javascript source code). -> String -- ^ The name of the Javascript source (filename or input device). -> Either String AST.JSNode -- ^ An error or maybe the abstract syntax tree (AST) of zero -- or more Javascript statements, plus comments. parse input _srcName = runAlex input parseProgram readJs :: String -> AST.JSNode readJs input = do case (parse input "src") of Left msg -> error (show msg) Right p -> p -- | Parse the given file. -- For UTF-8 support, make sure your locale is set such that -- "System.IO.localeEncoding" returns "utf8" parseFile :: FilePath -> IO AST.JSNode parseFile filename = do x <- readFile (filename) return $ readJs x -- | Parse the given file, explicitly setting the encoding to UTF8 -- when reading it parseFileUtf8 :: FilePath -> IO AST.JSNode parseFileUtf8 filename = do h <- openFile filename ReadMode hSetEncoding h utf8 x <- hGetContents h return $ readJs x showStripped :: AST.JSNode -> String showStripped ast = AST.showStripped ast showStrippedMaybe :: Show a => Either a AST.JSNode -> String showStrippedMaybe maybeAst = do case maybeAst of Left msg -> "Left (" ++ show msg ++ ")" Right p -> "Right (" ++ AST.showStripped p ++ ")" -- | Parse one compound statement, or a sequence of simple statements. -- Generally used for interactive input, such as from the command line of an interpreter. -- Return comments in addition to the parsed statements. parseUsing :: Alex AST.JSNode -- ^ The parser to be used -> String -- ^ The input stream (Javascript source code). -> String -- ^ The name of the Javascript source (filename or input device). -> Either String AST.JSNode -- ^ An error or maybe the abstract syntax tree (AST) of zero -- or more Javascript statements, plus comments. parseUsing p input _srcName = runAlex input p language-javascript-0.5.14.2/src/Language/JavaScript/Parser/ParserMonad.hs0000644000000000000000000000170512557503314024451 0ustar0000000000000000{-# OPTIONS #-} ----------------------------------------------------------------------------- -- | -- Module : Language.JavaScript.ParserMonad -- Copyright : (c) 2012 Alan Zimmerman -- License : BSD-style -- Stability : experimental -- Portability : ghc -- -- Monad support for JavaScript parser and lexer. ----------------------------------------------------------------------------- module Language.JavaScript.Parser.ParserMonad ( AlexUserState(..) , alexInitUserState ) where import Language.JavaScript.Parser.Token import Language.JavaScript.Parser.SrcLocation data AlexUserState = AlexUserState { previousToken :: !Token -- ^the previous token , comment :: [Token] -- ^the previous comment, if any } alexInitUserState :: AlexUserState alexInitUserState = AlexUserState { previousToken = initToken , comment = [] } initToken :: Token initToken = CommentToken tokenPosnEmpty "" [] language-javascript-0.5.14.2/src/Language/JavaScript/Parser/LexerUtils.hs0000644000000000000000000000731312557503314024337 0ustar0000000000000000----------------------------------------------------------------------------- -- | -- Module : Language.JavaScript.LexerUtils -- Based on language-python version by Bernie Pope -- Copyright : (c) 2009 Bernie Pope -- License : BSD-style -- Stability : experimental -- Portability : ghc -- -- Various utilities to support the JavaScript lexer. ----------------------------------------------------------------------------- module Language.JavaScript.Parser.LexerUtils ( StartCode -- , AlexInput -- , alexGetChar -- , alexInputPrevChar , symbolToken , mkString , commentToken , wsToken , regExToken , decimalToken -- , endOfLine , endOfFileToken , assignToken , hexIntegerToken , octalToken , stringToken --, lexicalError ) where --import Control.Monad.Error.Class (throwError) import Language.JavaScript.Parser.Token as Token import Language.JavaScript.Parser.SrcLocation import Prelude hiding (span) -- Functions for building tokens type StartCode = Int symbolToken :: Monad m => (TokenPosn -> [CommentAnnotation] -> Token) -> TokenPosn -> Int -> String -> m Token symbolToken mkToken location _ _ = return (mkToken location []) -- special tokens for the end of file and end of line endOfFileToken :: Token endOfFileToken = EOFToken tokenPosnEmpty [] mkString :: (Monad m) => (TokenPosn -> String -> Token) -> TokenPosn -> Int -> String -> m Token mkString toToken loc len str = do return (toToken loc (take len str)) decimalToken :: TokenPosn -> String -> Token decimalToken loc str = DecimalToken loc str [] hexIntegerToken :: TokenPosn -> String -> Token hexIntegerToken loc str = HexIntegerToken loc str [] octalToken :: TokenPosn -> String -> Token octalToken loc str = OctalToken loc str [] assignToken :: TokenPosn -> String -> Token assignToken loc str = AssignToken loc str [] regExToken :: TokenPosn -> String -> Token regExToken loc str = RegExToken loc str [] stringToken :: TokenPosn -> String -> Token stringToken loc str = StringToken loc str1 delimiter [] where str1 = init $ tail str -- str1 = stripLineContinuations $ init $ tail str delimiter = head str commentToken :: TokenPosn -> String -> Token commentToken loc str = CommentToken loc str [] wsToken :: TokenPosn -> String -> Token wsToken loc str = WsToken loc str [] -- --------------------------------------------------------------------- -- Strip out any embedded line continuations -- Recognise by \ followed by $lf | $cr | $ls | $ps | $cr $lf -- $ls = \x2028, $ps = \x2029 {- stripLineContinuations :: String -> String stripLineContinuations xs = doStripLineContinuations [] [] xs doStripLineContinuations :: String -> String -> String -> String doStripLineContinuations acc matched xs | xs == [] = acc -- Assume we are passed well-formed strings, should not be a dangling match | matched == [] = if (head xs == '\\') then doStripLineContinuations acc ['\\'] (tail xs) else doStripLineContinuations (acc ++ [head xs]) [] (tail xs) | otherwise = if ((head xs == '\n') || (head xs == '\r') || (head xs == '\x2028') || (head xs == '\x2029')) then doStripLineContinuations acc (matched++[head xs]) (tail xs) else (if (matched == ['\\']) then doStripLineContinuations (acc++matched ++ [head xs]) [] (tail xs) else doStripLineContinuations (acc++[head xs]) [] (tail xs)) -} -- ----------------------------------------------------------------------------- -- Functionality required by Alex {- lexicalError :: P a lexicalError = do location <- getLocation c <- liftM head getInput -- (_,c,_,_) <- getInput throwError $ UnexpectedChar c location -} -- EOF language-javascript-0.5.14.2/src/Language/JavaScript/Parser/Token.hs0000644000000000000000000002362212557503314023320 0ustar0000000000000000{-# LANGUAGE CPP, DeriveDataTypeable #-} ----------------------------------------------------------------------------- -- | -- Module : Language.Python.Common.Token -- Copyright : (c) 2009 Bernie Pope -- License : BSD-style -- Maintainer : bjpop@csse.unimelb.edu.au -- Stability : experimental -- Portability : ghc -- -- Lexical tokens for the Python lexer. Contains the superset of tokens from -- version 2 and version 3 of Python (they are mostly the same). ----------------------------------------------------------------------------- module Language.JavaScript.Parser.Token ( -- * The tokens Token (..) , CommentAnnotation (..) -- * String conversion , debugTokenString -- * Classification -- TokenClass (..), ) where import Data.Data import Language.JavaScript.Parser.SrcLocation data CommentAnnotation = CommentA TokenPosn String | WhiteSpace TokenPosn String | NoComment deriving (Eq, Show, Typeable, Data, Read) -- | Lexical tokens. -- Each may be annotated with any comment occuring between the prior token and this one data Token -- Comment = CommentToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } -- ^ Single line comment. | WsToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } -- ^ White space, for preservation. -- Identifiers | IdentifierToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } -- ^ Identifier. -- Javascript Literals | DecimalToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } -- ^ Literal: Decimal | HexIntegerToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } -- ^ Literal: Hexadecimal Integer | OctalToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } -- ^ Literal: Octal Integer | StringToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, token_delimiter :: !Char, tokenComment :: ![CommentAnnotation] } -- ^ Literal: string, delimited by either single or double quotes | RegExToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } -- ^ Literal: Regular Expression -- Keywords | BreakToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | CaseToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | CatchToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | ConstToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | ContinueToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | DebuggerToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | DefaultToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | DeleteToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | DoToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | ElseToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | EnumToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | FalseToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | FinallyToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | ForToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | FunctionToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | IfToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | InToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | InstanceofToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | NewToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | NullToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | ReturnToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | SwitchToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | ThisToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | ThrowToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | TrueToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | TryToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | TypeofToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | VarToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | VoidToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | WhileToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | WithToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } -- Future reserved words | FutureToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } -- Needed, not sure what they are though. | GetToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | SetToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } -- Delimiters -- Operators | AutoSemiToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | SemiColonToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | CommaToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | HookToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | ColonToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | OrToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | AndToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | BitwiseOrToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | BitwiseXorToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | BitwiseAndToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | StrictEqToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | EqToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | AssignToken { tokenSpan :: !TokenPosn, tokenLiteral :: !String, tokenComment :: ![CommentAnnotation] } | SimpleAssignToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | StrictNeToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | NeToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | LshToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | LeToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | LtToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | UrshToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | RshToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | GeToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | GtToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | IncrementToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | DecrementToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | PlusToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | MinusToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | MulToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | DivToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | ModToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | NotToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | BitwiseNotToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | DotToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | LeftBracketToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | RightBracketToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | LeftCurlyToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | RightCurlyToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | LeftParenToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | RightParenToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } | CondcommentEndToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } -- Special cases | TailToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } -- ^ Stuff between last JS and EOF | EOFToken { tokenSpan :: !TokenPosn, tokenComment :: ![CommentAnnotation] } -- ^ End of file deriving (Eq, Show, Typeable) -- | Produce a string from a token containing detailed information. Mainly intended for debugging. debugTokenString :: Token -> String debugTokenString = takeWhile (/= ' ') . show language-javascript-0.5.14.2/src/Language/JavaScript/Parser/AST.hs0000644000000000000000000002400012557503314022656 0ustar0000000000000000{-# LANGUAGE DeriveDataTypeable #-} module Language.JavaScript.Parser.AST ( Node (..) , JSNode(..) -- , TokenPosn (..) , showStripped ) where import Data.Data import Data.List import Language.JavaScript.Parser.SrcLocation (TokenPosn(..)) import Language.JavaScript.Parser.Token -- --------------------------------------------------------------------- -- |The JSNode is the building block of the AST. -- Each has a syntactic part 'Node'. In addition, the leaf elements -- (terminals) have a position 'TokenPosn', as well as an array of comments -- and/or whitespace that was collected while parsing. data JSNode = NN Node -- ^Non Terminal node, does not have any position or comment information | NT Node TokenPosn [CommentAnnotation] -- ^Terminal node, including position and comment/whitespace information deriving (Show, Eq, Read, Data, Typeable) data Node = -- | Terminals JSIdentifier String | JSDecimal String | JSLiteral String | JSHexInteger String | JSOctal String | JSStringLiteral Char [Char] | JSRegEx String -- | Non Terminals | JSArguments JSNode [JSNode] JSNode -- ^lb, args, rb | JSArrayLiteral JSNode [JSNode] JSNode -- ^lb, contents, rb | JSBlock [JSNode] [JSNode] [JSNode] -- ^optional lb,optional block statements,optional rb | JSBreak JSNode [JSNode] JSNode -- ^break, optional identifier, autosemi | JSCallExpression String [JSNode] [JSNode] [JSNode] -- ^type : ., (), []; opening [ or ., contents, closing | JSCase JSNode JSNode JSNode [JSNode] -- ^case,expr,colon,stmtlist | JSCatch JSNode JSNode JSNode [JSNode] JSNode JSNode -- ^ catch,lb,ident,[if,expr],rb,block | JSContinue JSNode [JSNode] JSNode -- ^continue,optional identifier,autosemi | JSDefault JSNode JSNode [JSNode] -- ^default,colon,stmtlist | JSDoWhile JSNode JSNode JSNode JSNode JSNode JSNode JSNode -- ^do,stmt,while,lb,expr,rb,autosemi | JSElision JSNode -- ^comma | JSExpression [JSNode] -- ^expression components | JSExpressionBinary String [JSNode] JSNode [JSNode] -- ^what, lhs, op, rhs | JSExpressionParen JSNode JSNode JSNode -- ^lb,expression,rb | JSExpressionPostfix String [JSNode] JSNode -- ^type, expression, operator | JSExpressionTernary [JSNode] JSNode [JSNode] JSNode [JSNode] -- ^cond, ?, trueval, :, falseval | JSFinally JSNode JSNode -- ^finally,block | JSFor JSNode JSNode [JSNode] JSNode [JSNode] JSNode [JSNode] JSNode JSNode -- ^for,lb,expr,semi,expr,semi,expr,rb.stmt | JSForIn JSNode JSNode [JSNode] JSNode JSNode JSNode JSNode -- ^for,lb,expr,in,expr,rb,stmt | JSForVar JSNode JSNode JSNode [JSNode] JSNode [JSNode] JSNode [JSNode] JSNode JSNode -- ^for,lb,var,vardecl,semi,expr,semi,expr,rb,stmt | JSForVarIn JSNode JSNode JSNode JSNode JSNode JSNode JSNode JSNode -- ^for,lb,var,vardecl,in,expr,rb,stmt | JSFunction JSNode JSNode JSNode [JSNode] JSNode JSNode -- ^fn,name, lb,parameter list,rb,block -- | JSFunctionBody [JSNode] -- ^body | JSFunctionExpression JSNode [JSNode] JSNode [JSNode] JSNode JSNode -- ^fn,[name],lb, parameter list,rb,block` | JSIf JSNode JSNode JSNode JSNode [JSNode] [JSNode] -- ^if,(,expr,),stmt,optional rest | JSLabelled JSNode JSNode JSNode -- ^identifier,colon,stmt | JSMemberDot [JSNode] JSNode JSNode -- ^firstpart, dot, name | JSMemberSquare [JSNode] JSNode JSNode JSNode -- ^firstpart, lb, expr, rb | JSObjectLiteral JSNode [JSNode] JSNode -- ^lbrace contents rbrace | JSOperator JSNode -- ^opnode | JSPropertyAccessor JSNode JSNode JSNode [JSNode] JSNode JSNode -- ^(get|set), name, lb, params, rb, block | JSPropertyNameandValue JSNode JSNode [JSNode] -- ^name, colon, value | JSReturn JSNode [JSNode] JSNode -- ^return,optional expression,autosemi -- | JSSourceElements [JSNode] -- ^source elements | JSSourceElementsTop [JSNode] -- ^source elements -- | JSStatementBlock JSNode JSNode JSNode -- ^lb,block,rb -- | JSStatementList [JSNode] -- ^statements | JSSwitch JSNode JSNode JSNode JSNode JSNode -- ^switch,lb,expr,rb,caseblock | JSThrow JSNode JSNode -- ^throw val | JSTry JSNode JSNode [JSNode] -- ^try,block,rest | JSUnary String JSNode -- ^type, operator | JSVarDecl JSNode [JSNode] -- ^identifier, optional initializer | JSVariables JSNode [JSNode] JSNode -- ^var|const, decl, autosemi | JSWhile JSNode JSNode JSNode JSNode JSNode -- ^while,lb,expr,rb,stmt | JSWith JSNode JSNode JSNode JSNode [JSNode] -- ^with,lb,expr,rb,stmt list deriving (Show, Eq, Read, Data, Typeable) -- Strip out the location info, leaving the original JSNode text representation showStripped :: JSNode -> String showStripped = ss -- Alias for internal use ss :: JSNode -> String ss (NN node ) = showStrippedNode node ss (NT node _ _) = showStrippedNode node sss :: [JSNode] -> String --sss xs = "[" ++ (concatMap ss xs) ++ "]" sss xs = "[" ++ (concat (intersperse "," $ map ss xs)) ++ "]" showStrippedNode :: Node -> String showStrippedNode (JSArguments _lb xs _rb) = "JSArguments " ++ sss xs showStrippedNode (JSArrayLiteral _lb xs _rb) = "JSArrayLiteral " ++ sss xs showStrippedNode (JSBlock _lb xs _rb) = "JSBlock (" ++ sss xs ++ ")" showStrippedNode (JSBreak _b x1s as) = "JSBreak " ++ sss x1s ++ " " ++ ss as showStrippedNode (JSCallExpression s _os xs _cs) = "JSCallExpression " ++ show s ++ " " ++ sss xs showStrippedNode (JSCase _ca x1 _c x2s) = "JSCase (" ++ ss x1 ++ ") (" ++ sss x2s ++ ")" showStrippedNode (JSCatch _c _lb x1 x2s _rb x3) = "JSCatch (" ++ ss x1 ++ ") " ++ sss x2s ++ " (" ++ ss x3 ++ ")" showStrippedNode (JSContinue _c xs as) = "JSContinue " ++ sss xs ++ " " ++ ss as showStrippedNode (JSDecimal s) = "JSDecimal " ++ show s showStrippedNode (JSDefault _d _c xs) = "JSDefault (" ++ sss xs ++ ")" showStrippedNode (JSDoWhile _d x1 _w _lb x2 _rb x3) = "JSDoWhile (" ++ ss x1 ++ ") (" ++ ss x2 ++ ") (" ++ ss x3 ++ ")" showStrippedNode (JSElision c) = "JSElision " ++ ss c showStrippedNode (JSExpression xs) = "JSExpression " ++ sss xs showStrippedNode (JSExpressionBinary s x2s _op x3s) = "JSExpressionBinary " ++ show s ++ " " ++ sss x2s ++ " " ++ sss x3s showStrippedNode (JSExpressionParen _lp x _rp) = "JSExpressionParen (" ++ ss x ++ ")" showStrippedNode (JSExpressionPostfix s xs _op) = "JSExpressionPostfix " ++ show s ++ " " ++ sss xs showStrippedNode (JSExpressionTernary x1s _q x2s _c x3s) = "JSExpressionTernary " ++ sss x1s ++ " " ++ sss x2s ++ " " ++ sss x3s showStrippedNode (JSFinally _f x) = "JSFinally (" ++ ss x ++ ")" showStrippedNode (JSFor _f _lb x1s _s1 x2s _s2 x3s _rb x4) = "JSFor " ++ sss x1s ++ " " ++ sss x2s ++ " " ++ sss x3s ++ " (" ++ ss x4 ++ ")" showStrippedNode (JSForIn _f _lb x1s _i x2 _rb x3) = "JSForIn " ++ sss x1s ++ " (" ++ ss x2 ++ ") (" ++ ss x3 ++ ")" showStrippedNode (JSForVar _f _lb _v x1s _s1 x2s _s2 x3s _rb x4) = "JSForVar " ++ sss x1s ++ " " ++ sss x2s ++ " " ++ sss x3s ++ " (" ++ ss x4 ++ ")" showStrippedNode (JSForVarIn _f _lb _v x1 _i x2 _rb x3) = "JSForVarIn (" ++ ss x1 ++ ") (" ++ ss x2 ++ ") (" ++ ss x3 ++ ")" showStrippedNode (JSFunction _f x1 _lb x2s _rb x3) = "JSFunction (" ++ ss x1 ++ ") " ++ sss x2s ++ " (" ++ ss x3 ++ ")" --showStrippedNode (JSFunctionBody xs) = "JSFunctionBody " ++ sss xs showStrippedNode (JSFunctionExpression _f x1s _lb x2s _rb x3) = "JSFunctionExpression " ++ sss x1s ++ " " ++ sss x2s ++ " (" ++ ss x3 ++ ")" showStrippedNode (JSHexInteger s) = "JSHexInteger " ++ show s showStrippedNode (JSOctal s) = "JSOctal " ++ show s showStrippedNode (JSIdentifier s) = "JSIdentifier " ++ show s showStrippedNode (JSIf _i _lb x1 _rb x2s x3s) = "JSIf (" ++ ss x1 ++ ") (" ++ sss x2s ++ ") (" ++ sss x3s ++ ")" showStrippedNode (JSLabelled x1 _c x2) = "JSLabelled (" ++ ss x1 ++ ") (" ++ ss x2 ++ ")" showStrippedNode (JSLiteral s) = "JSLiteral " ++ show s showStrippedNode (JSMemberDot x1s _d x2 ) = "JSMemberDot " ++ sss x1s ++ " (" ++ ss x2 ++ ")" showStrippedNode (JSMemberSquare x1s _lb x2 _rb) = "JSMemberSquare " ++ sss x1s ++ " (" ++ ss x2 ++ ")" showStrippedNode (JSObjectLiteral _lb xs _rb) = "JSObjectLiteral " ++ sss xs showStrippedNode (JSOperator n) = "JSOperator " ++ ss n showStrippedNode (JSPropertyNameandValue x1 _colon x2s) = "JSPropertyNameandValue (" ++ ss x1 ++ ") " ++ sss x2s showStrippedNode (JSPropertyAccessor s x1 _lb1 x2s _rb1 x3) = "JSPropertyAccessor " ++ show s ++ " (" ++ ss x1 ++ ") " ++ sss x2s ++ " (" ++ ss x3 ++ ")" showStrippedNode (JSRegEx s) = "JSRegEx " ++ show s showStrippedNode (JSReturn _r xs as) = "JSReturn " ++ sss xs ++ " " ++ ss as --showStrippedNode (JSSourceElements xs) = "JSSourceElements " ++ sss xs showStrippedNode (JSSourceElementsTop xs) = "JSSourceElementsTop " ++ sss xs -- showStrippedNode (JSStatementBlock _lb x _rb) = "JSStatementBlock (" ++ ss x ++ ")" -- showStrippedNode (JSStatementList xs) = "JSStatementList " ++ sss xs showStrippedNode (JSStringLiteral c s) = "JSStringLiteral " ++ show c ++ " " ++ show s showStrippedNode (JSSwitch _s _lb x _rb x2) = "JSSwitch (" ++ ss x ++ ") " ++ ss x2 showStrippedNode (JSThrow _t x) = "JSThrow (" ++ ss x ++ ")" showStrippedNode (JSTry _t x1 x2s) = "JSTry (" ++ ss x1 ++ ") " ++ sss x2s showStrippedNode (JSUnary s _x) = "JSUnary " ++ show s showStrippedNode (JSVarDecl x1 x2s) = "JSVarDecl (" ++ ss x1 ++ ") " ++ sss x2s showStrippedNode (JSVariables n xs _as) = "JSVariables " ++ ss n ++ " " ++ sss xs showStrippedNode (JSWhile _w _lb x1 _rb x2) = "JSWhile (" ++ ss x1 ++ ") (" ++ ss x2 ++ ")" showStrippedNode (JSWith _w _lb x1 _rb x2s) = "JSWith (" ++ ss x1 ++ ") " ++ sss x2s -- EOF language-javascript-0.5.14.2/src/Language/JavaScript/Parser/SrcLocation.hs0000644000000000000000000000126712557503314024461 0ustar0000000000000000{-# LANGUAGE DeriveDataTypeable #-} module Language.JavaScript.Parser.SrcLocation ( TokenPosn(..) , tokenPosnEmpty ) where import Data.Data -- | `TokenPosn' records the location of a token in the input text. It has three -- fields: the address (number of characters preceding the token), line number -- and column of a token within the file. -- Note: The lexer assumes the usual eight character tab stops. data TokenPosn = TokenPn !Int -- address (number of characters preceding the token) !Int -- line number !Int -- column deriving (Eq,Show, Read, Data, Typeable) tokenPosnEmpty :: TokenPosn tokenPosnEmpty = TokenPn 0 0 0 language-javascript-0.5.14.2/src/Language/JavaScript/Parser/StringEscape.hs0000644000000000000000000000725012557503314024626 0ustar0000000000000000{-# OPTIONS #-} ----------------------------------------------------------------------------- -- | -- Module : Language.Python.Common.StringEscape -- Copyright : (c) 2009 Bernie Pope -- License : BSD-style -- Maintainer : bjpop@csse.unimelb.edu.au -- Stability : experimental -- Portability : ghc -- -- Conversion to/from escaped characters in strings. Note: currently does not -- support escaped Unicode character names. -- -- See: -- -- * Version 2.6 -- -- * Version 3.1 ----------------------------------------------------------------------------- module Language.JavaScript.Parser.StringEscape ( -- * String conversion. unescapeString, unescapeRawString, -- * Digits allowed in octal and hex representation. octalDigits, hexDigits) where import Numeric (readHex, readOct) -- | Convert escaped sequences of characters into /real/ characters in a normal Python string. unescapeString :: String -> String unescapeString ('\\':'\\':cs) = '\\' : unescapeString cs -- Backslash (\) unescapeString ('\\':'\'':cs) = '\'' : unescapeString cs -- Single quote (') unescapeString ('\\':'"':cs) = '"' : unescapeString cs -- Double quote (") unescapeString ('\\':'a':cs) = '\a' : unescapeString cs -- ASCII Bell (BEL) unescapeString ('\\':'b':cs) = '\b' : unescapeString cs -- ASCII Backspace (BS) unescapeString ('\\':'f':cs) = '\f' : unescapeString cs -- ASCII Formfeed (FF) unescapeString ('\\':'n':cs) = '\n' : unescapeString cs -- ASCII Linefeed (LF) unescapeString ('\\':'r':cs) = '\r' : unescapeString cs -- ASCII Carriage Return (CR) unescapeString ('\\':'t':cs) = '\t' : unescapeString cs -- ASCII Horizontal Tab (TAB) unescapeString ('\\':'v':cs) = '\v' : unescapeString cs -- ASCII Vertical Tab (VT) unescapeString ('\\':'\n':cs) = unescapeString cs -- line continuation unescapeString ('\\':rest@(o:_)) | o `elem` octalDigits = unescapeNumeric 3 octalDigits (fst . head . readOct) rest unescapeString ('\\':'x':rest@(h:_)) | h `elem` hexDigits = unescapeNumeric 2 hexDigits (fst . head . readHex) rest unescapeString (c:cs) = c : unescapeString cs unescapeString [] = [] -- | Convert escaped sequences of characters into /real/ characters in a raw Python string. -- Note: despite their name, Python raw strings do allow a small set of character escapings, -- namely the single and double quote characters and the line continuation marker. unescapeRawString :: String -> String unescapeRawString ('\\':'\'':cs) = '\'' : unescapeRawString cs -- Single quote (') unescapeRawString ('\\':'"':cs) = '"' : unescapeRawString cs -- Double quote (") unescapeRawString ('\\':'\n':cs) = unescapeRawString cs -- line continuation unescapeRawString (c:cs) = c : unescapeRawString cs unescapeRawString [] = [] {- This is a bit complicated because Python allows between 1 and 3 octal characters after the \, and 1 and 2 hex characters after a \x. -} unescapeNumeric :: Int -> String -> (String -> Int) -> String -> String unescapeNumeric n numericDigits readNumeric str = loop n [] str where loop _ acc [] = [numericToChar acc] loop 0 acc rest = numericToChar acc : unescapeString rest loop n1 acc (c:cs) | c `elem` numericDigits = loop (n1-1) (c:acc) cs | otherwise = numericToChar acc : unescapeString (c:cs) numericToChar :: String -> Char numericToChar = toEnum . readNumeric . reverse octalDigits, hexDigits :: String -- | The set of valid octal digits in Python. octalDigits = "01234567" -- | The set of valid hex digits in Python. hexDigits = "0123456789abcdef" language-javascript-0.5.14.2/src/Language/JavaScript/Parser/Lexer.x0000644000000000000000000010724512557503314023160 0ustar0000000000000000{ module Language.JavaScript.Parser.Lexer ( Token(..) , AlexPosn(..) , Alex , lexCont , alexError , runAlex , alexTestTokeniser ) where import Language.JavaScript.Parser.LexerUtils import Language.JavaScript.Parser.ParserMonad import Language.JavaScript.Parser.SrcLocation import Language.JavaScript.Parser.Token import qualified Data.Map as Map } -- %wrapper "basic" -- %wrapper "monad" %wrapper "monadUserState" -- %wrapper "monad-bytestring" -- character sets $lf = \n -- line feed $cr = \r -- carriage return $ht = \t -- horizontal tab $sq = ' -- single quote $dq = \" -- double quote $digit = 0-9 -- digits $alpha = [a-zA-Z] -- alphabetic characters $digit = 0-9 $non_zero_digit = 1-9 $ident_letter = [a-zA-Z_] @eol_pattern = $lf | $cr $lf | $cr $lf $ls = \x2028 $ps = \x2029 @LineTerminatorSequence = $lf | $cr | $ls | $ps | $cr $lf $any_char = [\x00-\xff] $any_unicode_char = [\x00-\xffff] $eol_char = [\x000A\x000D\x2028\x2029] -- any end of line character -- $eol_char = [$lf $cr] -- any end of line character $not_eol_char = ~$eol_char -- anything but an end of line character -- From GOLD Parser -- {ID Head} = {Letter} + [_] + [$] @IDHead = $alpha | [_] | [\$] -- {ID Tail} = {Alphanumeric} + [_] + [$] @IDTail = $alpha | $digit | [_] | [\$] -- {String Chars1} = {Printable} + {HT} - ["\] -- {String Chars2} = {Printable} + {HT} - [\''] $StringChars1 = [$printable $ht] # [$dq \\] $StringChars2 = [$printable $ht] # [$sq \\] -- LineContinuation :: \ LineTerminatorSequence @LineContinuation = [\\] @LineTerminatorSequence $short_str_char = [^ \n \r ' \" \\] -- {Hex Digit} = {Digit} + [ABCDEF] + [abcdef] @HexDigit = $digit | [a-fA-F] -- {Oct Digit} = {Digit} + [01234567] @OctDigit = $digit | [0-7] -- {RegExp Chars} = {Letter}+{Digit}+['^']+['$']+['*']+['+']+['?']+['{']+['}']+['|']+['-']+['.']+[',']+['#']+['[']+[']']+['_']+['<']+['>'] -- $RegExpChars = [$alpha $digit \^\$\*\+\?\{\}\|\-\.\,\#\[\]\_\<\>] -- $RegExpChars = [$printable] # [\\] -- {Non Terminator} = {String Chars1} - {CR} - {LF} -- $NonTerminator = $StringChars1 # [$cr $lf] $NonTerminator = [$printable] # [$cr $lf] -- {Non Zero Digits}={Digit}-[0] -- ~ (LineTerminator | MUL | BSLASH | DIV) $RegExpFirstChar = [$printable] # [ $cr $lf \* \\ \/] -- ~ ( LineTerminator | BSLASH | DIV ) $RegExpChars = [$printable] # [ $cr $lf \\ \/] $MultiLineNotAsteriskChar = [$any_unicode_char] # [\*] $MultiLineNotForwardSlashOrAsteriskChar = [$any_unicode_char] # [\* \/] -- See http://blog.stevenlevithan.com/archives/javascript-regex-and-unicode -- * \u0009 — Tab — \t -- * \u000a — Line feed — \n — (newline character) -- * \u000b — Vertical tab — \v -- * \u000c — Form feed — \f -- * \u000d — Carriage return — \r — (newline character) -- * \u0020 — Space -- * \u00a0 — No-break space -- * \u1680 — Ogham space mark -- * \u180e — Mongolian vowel separator -- * \u2000 — En quad -- * \u2001 — Em quad -- * \u2002 — En space -- * \u2003 — Em space -- * \u2004 — Three-per-em space -- * \u2005 — Four-per-em space -- * \u2006 — Six-per-em space -- * \u2007 — Figure space -- * \u2008 — Punctuation space -- * \u2009 — Thin space -- * \u200a — Hair space -- * \u2028 — Line separator — (newline character) -- * \u2029 — Paragraph separator — (newline character) -- * \u202f — Narrow no-break space -- * \u205f — Medium mathematical space -- * \u3000 — Ideographic space -- $white_char = [\ \f\v\t\r\n] -- Note: from edition 5 the BOM (\xfeff) is also considered whitespace $white_char = [\x0009\x000a\x000b\x000c\x000d\x0020\x00a0\x1680\x180e\x2000\x2001\x2002\x2003\x2004\x2005\x2006\x2007\x2008\x2009\x200a\x2028\x2029\x202f\x205f\x3000\xfeff] -- Identifier characters -- UnicodeLetter -- any character in the Unicode categories “Uppercase letter (Lu)”, “Lowercase letter (Ll)”, -- “Titlecase letter (Lt)”, “Modifier letter (Lm)”, “Other letter (Lo)”, or “Letter number (Nl)”. -- http://www.fileformat.info/info/unicode/category/Lu/list.htm etc, see unicode/doit.sh $UnicodeLetter = [\x41-\x5a\x61-\x7a\xaa-\xaa\xb5-\xb5\xba-\xba\xc0-\xd6\xd8-\xf6\xf8-\x2c1\x2c6-\x2d1\x2e0-\x2e4\x2ec-\x2ec\x2ee-\x2ee\x370-\x374\x376-\x377\x37a-\x37d\x386-\x386\x388-\x38a\x38c-\x38c\x38e-\x3a1\x3a3-\x3f5\x3f7-\x481\x48a-\x527\x531-\x556\x559-\x559\x561-\x587\x5d0-\x5ea\x5f0-\x5f2\x620-\x64a\x66e-\x66f\x671-\x6d3\x6d5-\x6d5\x6e5-\x6e6\x6ee-\x6ef\x6fa-\x6fc\x6ff-\x6ff\x710-\x710\x712-\x72f\x74d-\x7a5\x7b1-\x7b1\x7ca-\x7ea\x7f4-\x7f5\x7fa-\x7fa\x800-\x815\x81a-\x81a\x824-\x824\x828-\x828\x840-\x858\x904-\x939\x93d-\x93d\x950-\x950\x958-\x961\x971-\x977\x979-\x97f\x985-\x98c\x98f-\x990\x993-\x9a8\x9aa-\x9b0\x9b2-\x9b2\x9b6-\x9b9\x9bd-\x9bd\x9ce-\x9ce\x9dc-\x9dd\x9df-\x9e1\x9f0-\x9f1\xa05-\xa0a\xa0f-\xa10\xa13-\xa28\xa2a-\xa30\xa32-\xa33\xa35-\xa36\xa38-\xa39\xa59-\xa5c\xa5e-\xa5e\xa72-\xa74\xa85-\xa8d\xa8f-\xa91\xa93-\xaa8\xaaa-\xab0\xab2-\xab3\xab5-\xab9\xabd-\xabd\xad0-\xad0\xae0-\xae1\xb05-\xb0c\xb0f-\xb10\xb13-\xb28\xb2a-\xb30\xb32-\xb33\xb35-\xb39\xb3d-\xb3d\xb5c-\xb5d\xb5f-\xb61\xb71-\xb71\xb83-\xb83\xb85-\xb8a\xb8e-\xb90\xb92-\xb95\xb99-\xb9a\xb9c-\xb9c\xb9e-\xb9f\xba3-\xba4\xba8-\xbaa\xbae-\xbb9\xbd0-\xbd0\xc05-\xc0c\xc0e-\xc10\xc12-\xc28\xc2a-\xc33\xc35-\xc39\xc3d-\xc3d\xc58-\xc59\xc60-\xc61\xc85-\xc8c\xc8e-\xc90\xc92-\xca8\xcaa-\xcb3\xcb5-\xcb9\xcbd-\xcbd\xcde-\xcde\xce0-\xce1\xcf1-\xcf2\xd05-\xd0c\xd0e-\xd10\xd12-\xd3a\xd3d-\xd3d\xd4e-\xd4e\xd60-\xd61\xd7a-\xd7f\xd85-\xd96\xd9a-\xdb1\xdb3-\xdbb\xdbd-\xdbd\xdc0-\xdc6\xe01-\xe30\xe32-\xe33\xe40-\xe46\xe81-\xe82\xe84-\xe84\xe87-\xe88\xe8a-\xe8a\xe8d-\xe8d\xe94-\xe97\xe99-\xe9f\xea1-\xea3\xea5-\xea5\xea7-\xea7\xeaa-\xeab\xead-\xeb0\xeb2-\xeb3\xebd-\xebd\xec0-\xec4\xec6-\xec6\xedc-\xedd\xf00-\xf00\xf40-\xf47\xf49-\xf6c\xf88-\xf8c\x1000-\x1000\x10000-\x1000b\x1000d-\x1000f\x1001-\x1001\x10010-\x1001f\x1002-\x1002\x10020-\x10026\x10028-\x1002f\x1003-\x1003\x10030-\x1003a\x1003c-\x1003d\x1003f-\x1003f\x1004-\x1004\x10040-\x1004d\x1005-\x1005\x10050-\x1005d\x1006-\x1008\x10080-\x1008f\x1009-\x1009\x10090-\x1009f\x100a-\x100a\x100a0-\x100af\x100b-\x100b\x100b0-\x100bf\x100c-\x100c\x100c0-\x100cf\x100d-\x100d\x100d0-\x100df\x100e-\x100e\x100e0-\x100ef\x100f-\x100f\x100f0-\x100fa\x1010-\x1014\x10140-\x1014f\x1015-\x1015\x10150-\x1015f\x1016-\x1016\x10160-\x1016f\x1017-\x1017\x10170-\x10174\x1018-\x1028\x10280-\x1028f\x1029-\x1029\x10290-\x1029c\x102a-\x102a\x102a0-\x102d0\x10300-\x1031e\x10330-\x1034a\x10380-\x1039d\x103a0-\x103c3\x103c8-\x103cf\x103d1-\x103d5\x103f-\x103f\x10400-\x1049d\x1050-\x1055\x105a-\x105d\x1061-\x1061\x1065-\x1066\x106e-\x1070\x1075-\x1080\x10800-\x10805\x10808-\x10808\x1080a-\x1080f\x1081-\x1081\x10810-\x10835\x10837-\x10838\x1083c-\x1083c\x1083f-\x10855\x108e-\x108e\x10900-\x10915\x10920-\x10939\x10a0-\x10a0\x10a00-\x10a00\x10a1-\x10a1\x10a10-\x10a13\x10a15-\x10a17\x10a19-\x10a1f\x10a2-\x10a2\x10a20-\x10a2f\x10a3-\x10a3\x10a30-\x10a33\x10a4-\x10a6\x10a60-\x10a6f\x10a7-\x10a7\x10a70-\x10a7c\x10a8-\x10b0\x10b00-\x10b0f\x10b1-\x10b1\x10b10-\x10b1f\x10b2-\x10b2\x10b20-\x10b2f\x10b3-\x10b3\x10b30-\x10b35\x10b4-\x10b4\x10b40-\x10b4f\x10b5-\x10b5\x10b50-\x10b55\x10b6-\x10b6\x10b60-\x10b6f\x10b7-\x10b7\x10b70-\x10b72\x10b8-\x10c0\x10c00-\x10c0f\x10c1-\x10c1\x10c10-\x10c1f\x10c2-\x10c2\x10c20-\x10c2f\x10c3-\x10c3\x10c30-\x10c3f\x10c4-\x10c4\x10c40-\x10c48\x10c5-\x10c5\x10d0-\x10fa\x10fc-\x10fc\x1100-\x1100\x11003-\x1100f\x1101-\x1101\x11010-\x1101f\x1102-\x1102\x11020-\x1102f\x1103-\x1103\x11030-\x11037\x1104-\x1108\x11083-\x1108f\x1109-\x1109\x11090-\x1109f\x110a-\x110a\x110a0-\x110af\x110b-\x1200\x12000-\x1200f\x1201-\x1201\x12010-\x1201f\x1202-\x1202\x12020-\x1202f\x1203-\x1203\x12030-\x1203f\x1204-\x1204\x12040-\x1204f\x1205-\x1205\x12050-\x1205f\x1206-\x1206\x12060-\x1206f\x1207-\x1207\x12070-\x1207f\x1208-\x1208\x12080-\x1208f\x1209-\x1209\x12090-\x1209f\x120a-\x120a\x120a0-\x120af\x120b-\x120b\x120b0-\x120bf\x120c-\x120c\x120c0-\x120cf\x120d-\x120d\x120d0-\x120df\x120e-\x120e\x120e0-\x120ef\x120f-\x120f\x120f0-\x120ff\x1210-\x1210\x12100-\x1210f\x1211-\x1211\x12110-\x1211f\x1212-\x1212\x12120-\x1212f\x1213-\x1213\x12130-\x1213f\x1214-\x1214\x12140-\x1214f\x1215-\x1215\x12150-\x1215f\x1216-\x1216\x12160-\x1216f\x1217-\x1217\x12170-\x1217f\x1218-\x1218\x12180-\x1218f\x1219-\x1219\x12190-\x1219f\x121a-\x121a\x121a0-\x121af\x121b-\x121b\x121b0-\x121bf\x121c-\x121c\x121c0-\x121cf\x121d-\x121d\x121d0-\x121df\x121e-\x121e\x121e0-\x121ef\x121f-\x121f\x121f0-\x121ff\x1220-\x1220\x12200-\x1220f\x1221-\x1221\x12210-\x1221f\x1222-\x1222\x12220-\x1222f\x1223-\x1223\x12230-\x1223f\x1224-\x1224\x12240-\x1224f\x1225-\x1225\x12250-\x1225f\x1226-\x1226\x12260-\x1226f\x1227-\x1227\x12270-\x1227f\x1228-\x1228\x12280-\x1228f\x1229-\x1229\x12290-\x1229f\x122a-\x122a\x122a0-\x122af\x122b-\x122b\x122b0-\x122bf\x122c-\x122c\x122c0-\x122cf\x122d-\x122d\x122d0-\x122df\x122e-\x122e\x122e0-\x122ef\x122f-\x122f\x122f0-\x122ff\x1230-\x1230\x12300-\x1230f\x1231-\x1231\x12310-\x1231f\x1232-\x1232\x12320-\x1232f\x1233-\x1233\x12330-\x1233f\x1234-\x1234\x12340-\x1234f\x1235-\x1235\x12350-\x1235f\x1236-\x1236\x12360-\x1236e\x1237-\x1240\x12400-\x1240f\x1241-\x1241\x12410-\x1241f\x1242-\x1242\x12420-\x1242f\x1243-\x1243\x12430-\x1243f\x1244-\x1244\x12440-\x1244f\x1245-\x1245\x12450-\x1245f\x1246-\x1246\x12460-\x12462\x1247-\x1248\x124a-\x124d\x1250-\x1256\x1258-\x1258\x125a-\x125d\x1260-\x1288\x128a-\x128d\x1290-\x12b0\x12b2-\x12b5\x12b8-\x12be\x12c0-\x12c0\x12c2-\x12c5\x12c8-\x12d6\x12d8-\x1300\x13000-\x1300f\x1301-\x1301\x13010-\x1301f\x1302-\x1302\x13020-\x1302f\x1303-\x1303\x13030-\x1303f\x1304-\x1304\x13040-\x1304f\x1305-\x1305\x13050-\x1305f\x1306-\x1306\x13060-\x1306f\x1307-\x1307\x13070-\x1307f\x1308-\x1308\x13080-\x1308f\x1309-\x1309\x13090-\x1309f\x130a-\x130a\x130a0-\x130af\x130b-\x130b\x130b0-\x130bf\x130c-\x130c\x130c0-\x130cf\x130d-\x130d\x130d0-\x130df\x130e-\x130e\x130e0-\x130ef\x130f-\x130f\x130f0-\x130ff\x1310-\x1310\x13100-\x1311f\x1312-\x1312\x13120-\x1312f\x1313-\x1313\x13130-\x1313f\x1314-\x1314\x13140-\x1314f\x1315-\x1315\x13150-\x1317f\x1318-\x1318\x13180-\x1318f\x1319-\x1319\x13190-\x1319f\x131a-\x131a\x131a0-\x131af\x131b-\x131b\x131b0-\x131bf\x131c-\x131c\x131c0-\x131cf\x131d-\x131d\x131d0-\x131df\x131e-\x131e\x131e0-\x131ef\x131f-\x131f\x131f0-\x131ff\x1320-\x1320\x13200-\x1320f\x1321-\x1321\x13210-\x1321f\x1322-\x1322\x13220-\x1322f\x1323-\x1323\x13230-\x1323f\x1324-\x1324\x13240-\x1324f\x1325-\x1325\x13250-\x1325f\x1326-\x1326\x13260-\x1326f\x1327-\x1327\x13270-\x1327f\x1328-\x1328\x13280-\x1328f\x1329-\x1329\x13290-\x1329f\x132a-\x132a\x132a0-\x132af\x132b-\x132b\x132b0-\x132bf\x132c-\x132c\x132c0-\x132cf\x132d-\x132d\x132d0-\x132df\x132e-\x132e\x132e0-\x132ef\x132f-\x132f\x132f0-\x132ff\x1330-\x1330\x13300-\x1330f\x1331-\x1331\x13310-\x1331f\x1332-\x1332\x13320-\x1332f\x1333-\x1333\x13330-\x1333f\x1334-\x1334\x13340-\x1334f\x1335-\x1335\x13350-\x1335f\x1336-\x1336\x13360-\x1336f\x1337-\x1337\x13370-\x1337f\x1338-\x1338\x13380-\x1338f\x1339-\x1339\x13390-\x1339f\x133a-\x133a\x133a0-\x133af\x133b-\x133b\x133b0-\x133bf\x133c-\x133c\x133c0-\x133cf\x133d-\x133d\x133d0-\x133df\x133e-\x133e\x133e0-\x133ef\x133f-\x133f\x133f0-\x133ff\x1340-\x1340\x13400-\x1340f\x1341-\x1341\x13410-\x1341f\x1342-\x1342\x13420-\x1342e\x1343-\x135a\x1380-\x138f\x13a0-\x13f4\x1401-\x166c\x166f-\x167f\x16800-\x1680f\x1681-\x1681\x16810-\x1681f\x1682-\x1682\x16820-\x1682f\x1683-\x1683\x16830-\x1683f\x1684-\x1684\x16840-\x1684f\x1685-\x1685\x16850-\x1685f\x1686-\x1686\x16860-\x1686f\x1687-\x1687\x16870-\x1687f\x1688-\x1688\x16880-\x1688f\x1689-\x1689\x16890-\x1689f\x168a-\x168a\x168a0-\x168af\x168b-\x168b\x168b0-\x168bf\x168c-\x168c\x168c0-\x168cf\x168d-\x168d\x168d0-\x168df\x168e-\x168e\x168e0-\x168ef\x168f-\x168f\x168f0-\x168ff\x1690-\x1690\x16900-\x1690f\x1691-\x1691\x16910-\x1691f\x1692-\x1692\x16920-\x1692f\x1693-\x1693\x16930-\x1693f\x1694-\x1694\x16940-\x1694f\x1695-\x1695\x16950-\x1695f\x1696-\x1696\x16960-\x1696f\x1697-\x1697\x16970-\x1697f\x1698-\x1698\x16980-\x1698f\x1699-\x1699\x16990-\x1699f\x169a-\x169a\x169a0-\x169ff\x16a0-\x16a0\x16a00-\x16a0f\x16a1-\x16a1\x16a10-\x16a1f\x16a2-\x16a2\x16a20-\x16a2f\x16a3-\x16a3\x16a30-\x16a38\x16a4-\x16ea\x16ee-\x16f0\x1700-\x170c\x170e-\x1711\x1720-\x1731\x1740-\x1751\x1760-\x176c\x176e-\x1770\x1780-\x17b3\x17d7-\x17d7\x17dc-\x17dc\x1820-\x1877\x1880-\x18a8\x18aa-\x18aa\x18b0-\x18f5\x1900-\x191c\x1950-\x196d\x1970-\x1974\x1980-\x19ab\x19c1-\x19c7\x1a00-\x1a16\x1a20-\x1a54\x1aa7-\x1aa7\x1b000-\x1b001\x1b05-\x1b33\x1b45-\x1b4b\x1b83-\x1ba0\x1bae-\x1baf\x1bc0-\x1be5\x1c00-\x1c23\x1c4d-\x1c4f\x1c5a-\x1c7d\x1ce9-\x1cec\x1cee-\x1cf1\x1d00-\x1d40\x1d400-\x1d40f\x1d41-\x1d41\x1d410-\x1d41f\x1d42-\x1d42\x1d420-\x1d42f\x1d43-\x1d43\x1d430-\x1d43f\x1d44-\x1d44\x1d440-\x1d44f\x1d45-\x1d45\x1d450-\x1d454\x1d456-\x1d45f\x1d46-\x1d46\x1d460-\x1d46f\x1d47-\x1d47\x1d470-\x1d47f\x1d48-\x1d48\x1d480-\x1d48f\x1d49-\x1d49\x1d490-\x1d49c\x1d49e-\x1d49f\x1d4a-\x1d4a\x1d4a2-\x1d4a2\x1d4a5-\x1d4a6\x1d4a9-\x1d4ac\x1d4ae-\x1d4af\x1d4b-\x1d4b\x1d4b0-\x1d4b9\x1d4bb-\x1d4bb\x1d4bd-\x1d4bf\x1d4c-\x1d4c\x1d4c0-\x1d4c3\x1d4c5-\x1d4cf\x1d4d-\x1d4d\x1d4d0-\x1d4df\x1d4e-\x1d4e\x1d4e0-\x1d4ef\x1d4f-\x1d4f\x1d4f0-\x1d4ff\x1d50-\x1d50\x1d500-\x1d505\x1d507-\x1d50a\x1d50d-\x1d50f\x1d51-\x1d51\x1d510-\x1d514\x1d516-\x1d51c\x1d51e-\x1d51f\x1d52-\x1d52\x1d520-\x1d52f\x1d53-\x1d53\x1d530-\x1d539\x1d53b-\x1d53e\x1d54-\x1d54\x1d540-\x1d544\x1d546-\x1d546\x1d54a-\x1d54f\x1d55-\x1d55\x1d550-\x1d550\x1d552-\x1d55f\x1d56-\x1d56\x1d560-\x1d56f\x1d57-\x1d57\x1d570-\x1d57f\x1d58-\x1d58\x1d580-\x1d58f\x1d59-\x1d59\x1d590-\x1d59f\x1d5a-\x1d5a\x1d5a0-\x1d5af\x1d5b-\x1d5b\x1d5b0-\x1d5bf\x1d5c-\x1d5c\x1d5c0-\x1d5cf\x1d5d-\x1d5d\x1d5d0-\x1d5df\x1d5e-\x1d5e\x1d5e0-\x1d5ef\x1d5f-\x1d5f\x1d5f0-\x1d5ff\x1d60-\x1d60\x1d600-\x1d60f\x1d61-\x1d61\x1d610-\x1d61f\x1d62-\x1d62\x1d620-\x1d62f\x1d63-\x1d63\x1d630-\x1d63f\x1d64-\x1d64\x1d640-\x1d64f\x1d65-\x1d65\x1d650-\x1d65f\x1d66-\x1d66\x1d660-\x1d66f\x1d67-\x1d67\x1d670-\x1d67f\x1d68-\x1d68\x1d680-\x1d68f\x1d69-\x1d69\x1d690-\x1d69f\x1d6a-\x1d6a\x1d6a0-\x1d6a5\x1d6a8-\x1d6af\x1d6b-\x1d6b\x1d6b0-\x1d6bf\x1d6c-\x1d6c\x1d6c0-\x1d6c0\x1d6c2-\x1d6cf\x1d6d-\x1d6d\x1d6d0-\x1d6da\x1d6dc-\x1d6df\x1d6e-\x1d6e\x1d6e0-\x1d6ef\x1d6f-\x1d6f\x1d6f0-\x1d6fa\x1d6fc-\x1d6ff\x1d70-\x1d70\x1d700-\x1d70f\x1d71-\x1d71\x1d710-\x1d714\x1d716-\x1d71f\x1d72-\x1d72\x1d720-\x1d72f\x1d73-\x1d73\x1d730-\x1d734\x1d736-\x1d73f\x1d74-\x1d74\x1d740-\x1d74e\x1d75-\x1d75\x1d750-\x1d75f\x1d76-\x1d76\x1d760-\x1d76e\x1d77-\x1d77\x1d770-\x1d77f\x1d78-\x1d78\x1d780-\x1d788\x1d78a-\x1d78f\x1d79-\x1d79\x1d790-\x1d79f\x1d7a-\x1d7a\x1d7a0-\x1d7a8\x1d7aa-\x1d7af\x1d7b-\x1d7b\x1d7b0-\x1d7bf\x1d7c-\x1d7c\x1d7c0-\x1d7c2\x1d7c4-\x1d7cb\x1d7d-\x1dbf\x1e00-\x1f15\x1f18-\x1f1d\x1f20-\x1f45\x1f48-\x1f4d\x1f50-\x1f57\x1f59-\x1f59\x1f5b-\x1f5b\x1f5d-\x1f5d\x1f5f-\x1f7d\x1f80-\x1fb4\x1fb6-\x1fbc\x1fbe-\x1fbe\x1fc2-\x1fc4\x1fc6-\x1fcc\x1fd0-\x1fd3\x1fd6-\x1fdb\x1fe0-\x1fec\x1ff2-\x1ff4\x1ff6-\x1ffc\x20000-\x20000\x2071-\x2071\x207f-\x207f\x2090-\x209c\x2102-\x2102\x2107-\x2107\x210a-\x2113\x2115-\x2115\x2119-\x211d\x2124-\x2124\x2126-\x2126\x2128-\x2128\x212a-\x212d\x212f-\x2139\x213c-\x213f\x2145-\x2149\x214e-\x214e\x2160-\x2188\x2a6d6-\x2a6d6\x2a700-\x2a700\x2b734-\x2b734\x2b740-\x2b740\x2b81d-\x2b81d\x2c00-\x2c2e\x2c30-\x2c5e\x2c60-\x2ce4\x2ceb-\x2cee\x2d00-\x2d25\x2d30-\x2d65\x2d6f-\x2d6f\x2d80-\x2d96\x2da0-\x2da6\x2da8-\x2dae\x2db0-\x2db6\x2db8-\x2dbe\x2dc0-\x2dc6\x2dc8-\x2dce\x2dd0-\x2dd6\x2dd8-\x2dde\x2e2f-\x2e2f\x2f800-\x2fa1d\x3005-\x3007\x3021-\x3029\x3031-\x3035\x3038-\x303c\x3041-\x3096\x309d-\x309f\x30a1-\x30fa\x30fc-\x30ff\x3105-\x312d\x3131-\x318e\x31a0-\x31ba\x31f0-\x31ff\x3400-\x3400\x4db5-\x4db5\x4e00-\x4e00\x9fcb-\x9fcb\xa000-\xa48c\xa4d0-\xa4fd\xa500-\xa60c\xa610-\xa61f\xa62a-\xa62b\xa640-\xa66e\xa67f-\xa697\xa6a0-\xa6ef\xa717-\xa71f\xa722-\xa788\xa78b-\xa78e\xa790-\xa791\xa7a0-\xa7a9\xa7fa-\xa801\xa803-\xa805\xa807-\xa80a\xa80c-\xa822\xa840-\xa873\xa882-\xa8b3\xa8f2-\xa8f7\xa8fb-\xa8fb\xa90a-\xa925\xa930-\xa946\xa960-\xa97c\xa984-\xa9b2\xa9cf-\xa9cf\xaa00-\xaa28\xaa40-\xaa42\xaa44-\xaa4b\xaa60-\xaa76\xaa7a-\xaa7a\xaa80-\xaaaf\xaab1-\xaab1\xaab5-\xaab6\xaab9-\xaabd\xaac0-\xaac0\xaac2-\xaac2\xaadb-\xaadd\xab01-\xab06\xab09-\xab0e\xab11-\xab16\xab20-\xab26\xab28-\xab2e\xabc0-\xabe2\xac00-\xac00\xd7a3-\xd7a3\xd7b0-\xd7c6\xd7cb-\xd7fb\xf900-\xfa2d\xfa30-\xfa6d\xfa70-\xfad9\xfb00-\xfb06\xfb13-\xfb17\xfb1d-\xfb1d\xfb1f-\xfb28\xfb2a-\xfb36\xfb38-\xfb3c\xfb3e-\xfb3e\xfb40-\xfb41\xfb43-\xfb44\xfb46-\xfbb1\xfbd3-\xfd3d\xfd50-\xfd8f\xfd92-\xfdc7\xfdf0-\xfdfb\xfe70-\xfe74\xfe76-\xfefc\xff21-\xff3a\xff41-\xff5a\xff66-\xffbe\xffc2-\xffc7\xffca-\xffcf\xffd2-\xffd7] -- UnicodeCombiningMark -- any character in the Unicode categories “Non-spacing mark (Mn)” or “Combining spacing mark (Mc)” $UnicodeCombiningMark = [\x300-\x36f\x483-\x487\x591-\x5bd\x5bf-\x5bf\x5c1-\x5c2\x5c4-\x5c5\x5c7-\x5c7\x610-\x61a\x64b-\x65f\x670-\x670\x6d6-\x6dc\x6df-\x6e4\x6e7-\x6e8\x6ea-\x6ed\x711-\x711\x730-\x74a\x7a6-\x7b0\x7eb-\x7f3\x816-\x819\x81b-\x823\x825-\x827\x829-\x82d\x859-\x85b\x900-\x903\x93a-\x93c\x93e-\x94f\x951-\x957\x962-\x963\x981-\x983\x9bc-\x9bc\x9be-\x9c4\x9c7-\x9c8\x9cb-\x9cd\x9d7-\x9d7\x9e2-\x9e3\xa01-\xa03\xa3c-\xa3c\xa3e-\xa42\xa47-\xa48\xa4b-\xa4d\xa51-\xa51\xa70-\xa71\xa75-\xa75\xa81-\xa83\xabc-\xabc\xabe-\xac5\xac7-\xac9\xacb-\xacd\xae2-\xae3\xb01-\xb03\xb3c-\xb3c\xb3e-\xb44\xb47-\xb48\xb4b-\xb4d\xb56-\xb57\xb62-\xb63\xb82-\xb82\xbbe-\xbc2\xbc6-\xbc8\xbca-\xbcd\xbd7-\xbd7\xc01-\xc03\xc3e-\xc44\xc46-\xc48\xc4a-\xc4d\xc55-\xc56\xc62-\xc63\xc82-\xc83\xcbc-\xcbc\xcbe-\xcc4\xcc6-\xcc8\xcca-\xccd\xcd5-\xcd6\xce2-\xce3\xd02-\xd03\xd3e-\xd44\xd46-\xd48\xd4a-\xd4d\xd57-\xd57\xd62-\xd63\xd82-\xd83\xdca-\xdca\xdcf-\xdd4\xdd6-\xdd6\xdd8-\xddf\xdf2-\xdf3\xe31-\xe31\xe34-\xe3a\xe47-\xe4e\xeb1-\xeb1\xeb4-\xeb9\xebb-\xebc\xec8-\xecd\xf18-\xf19\xf35-\xf35\xf37-\xf37\xf39-\xf39\xf3e-\xf3f\xf71-\xf84\xf86-\xf87\xf8d-\xf97\xf99-\xfbc\xfc6-\xfc6\x101fd-\x101fd\x102b-\x103e\x1056-\x1059\x105e-\x1060\x1062-\x1064\x1067-\x106d\x1071-\x1074\x1082-\x108d\x108f-\x108f\x109a-\x109d\x10a01-\x10a03\x10a05-\x10a06\x10a0c-\x10a0f\x10a38-\x10a3a\x10a3f-\x10a3f\x11000-\x11002\x11038-\x11046\x11080-\x11082\x110b0-\x110ba\x135d-\x135f\x1712-\x1714\x1732-\x1734\x1752-\x1753\x1772-\x1773\x17b6-\x17d3\x17dd-\x17dd\x180b-\x180d\x18a9-\x18a9\x1920-\x192b\x1930-\x193b\x19b0-\x19c0\x19c8-\x19c9\x1a17-\x1a1b\x1a55-\x1a5e\x1a60-\x1a7c\x1a7f-\x1a7f\x1b00-\x1b04\x1b34-\x1b44\x1b6b-\x1b73\x1b80-\x1b82\x1ba1-\x1baa\x1be6-\x1bf3\x1c24-\x1c37\x1cd0-\x1cd2\x1cd4-\x1ce8\x1ced-\x1ced\x1cf2-\x1cf2\x1d165-\x1d169\x1d16d-\x1d172\x1d17b-\x1d182\x1d185-\x1d18b\x1d1aa-\x1d1ad\x1d242-\x1d244\x1dc0-\x1de6\x1dfc-\x1dff\x20d0-\x20dc\x20e1-\x20e1\x20e5-\x20f0\x2cef-\x2cf1\x2d7f-\x2d7f\x2de0-\x2dff\x302a-\x302f\x3099-\x309a\xa66f-\xa66f\xa67c-\xa67d\xa6f0-\xa6f1\xa802-\xa802\xa806-\xa806\xa80b-\xa80b\xa823-\xa827\xa880-\xa881\xa8b4-\xa8c4\xa8e0-\xa8f1\xa926-\xa92d\xa947-\xa953\xa980-\xa983\xa9b3-\xa9c0\xaa29-\xaa36\xaa43-\xaa43\xaa4c-\xaa4d\xaa7b-\xaa7b\xaab0-\xaab0\xaab2-\xaab4\xaab7-\xaab8\xaabe-\xaabf\xaac1-\xaac1\xabe3-\xabea\xabec-\xabed\xe0100-\xe01ef\xfb1e-\xfb1e\xfe00-\xfe0f] -- UnicodeDigit -- any character in the Unicode category “Decimal number (Nd)” $UnicodeDigit = [\x30-\x39\x660-\x669\x6f0-\x6f9\x7c0-\x7c9\x966-\x96f\x9e6-\x9ef\xa66-\xa6f\xae6-\xaef\xb66-\xb6f\xbe6-\xbef\xc66-\xc6f\xce6-\xcef\xd66-\xd6f\xe50-\xe59\xed0-\xed9\xf20-\xf29\x1040-\x1049\x104a0-\x104a9\x1090-\x1099\x11066-\x1106f\x17e0-\x17e9\x1810-\x1819\x1946-\x194f\x19d0-\x19d9\x1a80-\x1a89\x1a90-\x1a99\x1b50-\x1b59\x1bb0-\x1bb9\x1c40-\x1c49\x1c50-\x1c59\x1d7ce-\x1d7ff\xa620-\xa629\xa8d0-\xa8d9\xa900-\xa909\xa9d0-\xa9d9\xaa50-\xaa59\xabf0-\xabf9] -- UnicodeConnectorPunctuation -- any character in the Unicode category “Connector punctuation (Pc)” $UnicodeConnectorPunctuation = [\x5f-\x5f\x203f-\x2040\x2054-\x2054\xfe33-\xfe34\xfe4d-\xfe4f] -- UnicodeEscapeSequence :: -- u HexDigit HexDigit HexDigit HexDigit $HexDigit = [0-9a-fA-F] @UnicodeEscapeSequence = u $HexDigit $HexDigit $HexDigit $HexDigit -- IdentifierStart :: -- UnicodeLetter -- $ -- _ -- \ UnicodeEscapeSequence @IdentifierStart = $UnicodeLetter | [\$] | [_] | [\\] @UnicodeEscapeSequence -- IdentifierPart :: -- IdentifierStart -- UnicodeCombiningMark -- UnicodeDigit -- UnicodeConnectorPunctuation -- \ UnicodeEscapeSequence $ZWNJ = [\x200c] $ZWJ = [\x200d] @IdentifierPart = @IdentifierStart | $UnicodeCombiningMark | $UnicodeDigit | UnicodeConnectorPunctuation [\\] @UnicodeEscapeSequence | $ZWNJ | $ZWJ -- ! ------------------------------------------------- Terminals tokens :- -- State: 0 is regex allowed, 1 is / or /= allowed <0> () ; -- { registerStates lexToken reg divide } -- Skip Whitespace $white_char+ { adapt (mkString wsToken) } -- Skip one line comment "//"($not_eol_char)* { adapt (mkString commentToken) } -- --------------------------------------------------------------------- -- Comment definition from the ECMAScript spec, ver 3 -- 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 * -- Skip multi-line comments. Note: may not nest -- "/*"($any_char)*"*/" ; -- "/*" (($MultiLineNotAsteriskChar)*| ("*")+ ($MultiLineNotForwardSlashOrAsteriskChar) )* ("*")+ "/" ; "/*" (($MultiLineNotAsteriskChar)*| ("*")+ ($MultiLineNotForwardSlashOrAsteriskChar) )* ("*")+ "/" { adapt (mkString commentToken) } -- Identifier = {ID Head}{ID Tail}* -- @IDHead(@IDTail)* { \loc len str -> keywordOrIdent (take len str) loc } @IdentifierStart(@IdentifierPart)* { \ap@(loc,_,_,str) len -> keywordOrIdent (take len str) (toTokenPosn loc) } -- StringLiteral = '"' ( {String Chars1} | '\' {Printable} )* '"' -- | '' ( {String Chars2} | '\' {Printable} )* '' $dq ( $StringChars1 | \\ $printable | @LineContinuation )* $dq | $sq ( $StringChars2 | \\ $printable | @LineContinuation )* $sq { adapt (mkString stringToken) } -- HexIntegerLiteral = '0x' {Hex Digit}+ ("0x"|"0X") @HexDigit+ { adapt (mkString hexIntegerToken) } -- OctalLiteral = '0' {Octal Digit}+ ("0") @OctDigit+ { adapt (mkString octalToken) } -- RegExp = '/' ({RegExp Chars} | '\' {Non Terminator})+ '/' ( 'g' | 'i' | 'm' )* -- "/" ($RegExpChars | "\" $NonTerminator)+ "/" ("g"|"i"|"m")* { mkString regExToken } -- Based on the Jint version "/" ($RegExpFirstChar | "\" $NonTerminator) ($RegExpChars | "\" $NonTerminator)* "/" ("g"|"i"|"m")* { adapt (mkString regExToken) } -- TODO: Work in SignedInteger -- DecimalLiteral= {Non Zero Digits}+ '.' {Digit}* ('e' | 'E' ) {Non Zero Digits}+ {Digit}* -- | {Non Zero Digits}+ '.' {Digit}* -- | '0' '.' {Digit}+ ('e' | 'E' ) {Non Zero Digits}+ {Digit}* -- | {Non Zero Digits}+ {Digit}* -- | '0' -- | '0' '.' {Digit}+ -- $non_zero_digit $digit* "." $digit* ("e"|"E") ("+"|"-")? $non_zero_digit+ $digit* -- | $non_zero_digit $digit* "." $digit* -- | "0." $digit+ ("e"|"E") ("+"|"-")? $non_zero_digit+ $digit* -- | $non_zero_digit+ $digit* -- | "0" -- | "0." $digit+ { mkString decimalToken } "0" "." $digit* ("e"|"E") ("+"|"-")? $digit+ | $non_zero_digit $digit* "." $digit* ("e"|"E") ("+"|"-")? $digit+ | "." $digit+ ("e"|"E") ("+"|"-")? $digit+ | "0" ("e"|"E") ("+"|"-")? $digit+ | $non_zero_digit $digit* ("e"|"E") ("+"|"-")? $digit+ -- ++FOO++ | "0" "." $digit* | $non_zero_digit $digit* "." $digit* | "." $digit+ | "0" | $non_zero_digit $digit* { adapt (mkString decimalToken) } -- beginning of file { @eol_pattern ; -- @eol_pattern { endOfLine lexToken } -- @eol_pattern { endOfLine alexMonadScan } } -- / or /= only allowed in state 1 { "/=" { adapt (mkString assignToken)} "/" { adapt (symbolToken DivToken)} } { ";" { adapt (symbolToken SemiColonToken)} "," { adapt (symbolToken CommaToken)} "?" { adapt (symbolToken HookToken)} ":" { adapt (symbolToken ColonToken)} "||" { adapt (symbolToken OrToken)} "&&" { adapt (symbolToken AndToken)} "|" { adapt (symbolToken BitwiseOrToken)} "^" { adapt (symbolToken BitwiseXorToken)} "&" { adapt (symbolToken BitwiseAndToken)} "===" { adapt (symbolToken StrictEqToken)} "==" { adapt (symbolToken EqToken)} "*=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | ">>>=" | "&=" | "^=" | "|=" { adapt (mkString assignToken)} "=" { adapt (symbolToken SimpleAssignToken)} "!==" { adapt (symbolToken StrictNeToken)} "!=" { adapt (symbolToken NeToken)} "<<" { adapt (symbolToken LshToken)} "<=" { adapt (symbolToken LeToken)} "<" { adapt (symbolToken LtToken)} ">>>" { adapt (symbolToken UrshToken)} ">>" { adapt (symbolToken RshToken)} ">=" { adapt (symbolToken GeToken)} ">" { adapt (symbolToken GtToken)} "++" { adapt (symbolToken IncrementToken)} "--" { adapt (symbolToken DecrementToken)} "+" { adapt (symbolToken PlusToken)} "-" { adapt (symbolToken MinusToken)} "*" { adapt (symbolToken MulToken)} "%" { adapt (symbolToken ModToken)} "!" { adapt (symbolToken NotToken)} "~" { adapt (symbolToken BitwiseNotToken)} "." { adapt (symbolToken DotToken)} "[" { adapt (symbolToken LeftBracketToken)} "]" { adapt (symbolToken RightBracketToken)} "{" { adapt (symbolToken LeftCurlyToken)} "}" { adapt (symbolToken RightCurlyToken)} "(" { adapt (symbolToken LeftParenToken)} ")" { adapt (symbolToken RightParenToken)} "@*/" { adapt (symbolToken CondcommentEndToken)} } { {- -- The next function select between the two lex input states, as called for in -- secion 7 of ECMAScript Language Specification, Edition 3, 24 March 2000. The method is inspired by the lexer in http://jint.codeplex.com/ -} classifyToken :: Token -> Int classifyToken aToken = case aToken of IdentifierToken {} -> divide NullToken {} -> divide TrueToken {} -> divide FalseToken {} -> divide ThisToken {} -> divide OctalToken {} -> divide DecimalToken {} -> divide HexIntegerToken {} -> divide StringToken {} -> divide RightCurlyToken {} -> divide RightParenToken {} -> divide RightBracketToken {} -> divide _other -> reg lexToken :: Alex Token lexToken = do inp <- alexGetInput lt <- getLastToken case lt of TailToken {} -> alexEOF _other -> case alexScan inp (classifyToken lt) of AlexEOF -> do tok <- tailToken setLastToken tok return tok AlexError (pos,_,_,_) -> alexError ("lexical error @ line " ++ show (getLineNum(pos)) ++ " and column " ++ show (getColumnNum(pos))) AlexSkip inp' _len -> do alexSetInput inp' lexToken AlexToken inp' len action -> do alexSetInput inp' tok <- action inp len setLastToken tok return tok -- For tesing. alexTestTokeniser :: String -> Either String [Token] alexTestTokeniser input = runAlex input $ loop [] where loop acc = do tok <- lexToken case tok of EOFToken {} -> return $ case acc of [] -> [] (TailToken{}:xs) -> reverse xs xs -> reverse xs _ -> loop (tok:acc) -- This is called by the Happy parser. lexCont :: (Token -> Alex a) -> Alex a lexCont cont = do lexLoop where lexLoop = do tok <- lexToken case tok of CommentToken {} -> do addComment tok lexLoop WsToken {} -> do addComment tok ltok <- getLastToken case ltok of BreakToken {} -> maybeAutoSemi tok ContinueToken {} -> maybeAutoSemi tok ReturnToken {} -> maybeAutoSemi tok _otherwise -> lexLoop _other -> do cs <- getComment let tok' = tok{ tokenComment=(toCommentAnnotation cs) } setComment [] cont tok' -- If the token is a WsToken and it contains a newline, convert it to an -- AutoSemiToken and call the continuation, otherwise, just lexLoop. maybeAutoSemi ws@(WsToken sp tl cmt) = if any (== '\n') tl then cont $ AutoSemiToken sp tl cmt else lexLoop maybeAutoSemi _ = lexLoop toCommentAnnotation :: [Token] -> [CommentAnnotation] toCommentAnnotation [] = [NoComment] toCommentAnnotation xs = reverse $ map go xs where go tok@(CommentToken {}) = (CommentA (tokenSpan tok) (tokenLiteral tok)) go tok@(WsToken {}) = (WhiteSpace (tokenSpan tok) (tokenLiteral tok)) go _ = error "toCommentAnnotation" -- --------------------------------------------------------------------- getLineNum :: AlexPosn -> Int getLineNum (AlexPn _offset lineNum _colNum) = lineNum getColumnNum :: AlexPosn -> Int getColumnNum (AlexPn _offset _lineNum colNum) = colNum -- --------------------------------------------------------------------- getLastToken :: Alex Token getLastToken = Alex $ \s@AlexState{alex_ust=ust} -> Right (s, previousToken ust) setLastToken :: Token -> Alex () setLastToken (WsToken {}) = Alex $ \s -> Right (s, ()) setLastToken tok = Alex $ \s -> Right (s{alex_ust=(alex_ust s){previousToken=tok}}, ()) getComment :: Alex [Token] getComment = Alex $ \s@AlexState{alex_ust=ust} -> Right (s, comment ust) addComment :: Token -> Alex () addComment c = Alex $ \s -> Right (s{alex_ust=(alex_ust s){comment=c:( comment (alex_ust s) )}}, ()) setComment :: [Token] -> Alex () setComment cs = Alex $ \s -> Right (s{alex_ust=(alex_ust s){comment=cs }}, ()) alexEOF :: Alex Token alexEOF = do return (EOFToken tokenPosnEmpty []) tailToken :: Alex Token tailToken = do return (TailToken tokenPosnEmpty []) adapt :: (TokenPosn -> Int -> String -> Alex Token) -> AlexInput -> Int -> Alex Token adapt f ((AlexPn offset line col),_,_,inp) len = f (TokenPn offset line col) len inp toTokenPosn :: AlexPosn -> TokenPosn toTokenPosn (AlexPn offset line col) = (TokenPn offset line col) -- --------------------------------------------------------------------- -- a keyword or an identifier (the syntax overlaps) keywordOrIdent :: String -> TokenPosn -> Alex Token keywordOrIdent str location = return $ case Map.lookup str keywords of Just symbol -> symbol location str [] Nothing -> IdentifierToken location str [] -- mapping from strings to keywords -- keywords :: Map.Map String (TokenPosn -> String -> Token) keywords :: Map.Map String (TokenPosn -> String -> [CommentAnnotation] -> Token) keywords = Map.fromList keywordNames -- keywordNames :: [(String, TokenPosn -> String -> Token)] keywordNames :: [(String, TokenPosn -> String -> [CommentAnnotation] -> Token)] keywordNames = [ ( "break", BreakToken ) , ( "case", CaseToken ) , ( "catch", CatchToken ) , ( "const", ConstToken ) -- not a keyword, nominally a future reserved word, but actually in use , ( "continue", ContinueToken ) , ( "debugger", DebuggerToken ) , ( "default", DefaultToken ) , ( "delete", DeleteToken ) , ( "do", DoToken ) , ( "else", ElseToken ) , ( "enum", EnumToken ) -- not a keyword, nominally a future reserved word, but actually in use , ( "false", FalseToken ) -- boolean literal , ( "finally", FinallyToken ) , ( "for", ForToken ) , ( "function", FunctionToken ) , ( "if", IfToken ) , ( "in", InToken ) , ( "instanceof", InstanceofToken ) , ( "new", NewToken ) , ( "null", NullToken ) -- null literal , ( "return", ReturnToken ) , ( "switch", SwitchToken ) , ( "this", ThisToken ) , ( "throw", ThrowToken ) , ( "true", TrueToken ) , ( "try", TryToken ) , ( "typeof", TypeofToken ) , ( "var", VarToken ) , ( "void", VoidToken ) , ( "while", WhileToken ) , ( "with", WithToken ) -- TODO: no idea if these are reserved or not, but they are needed -- handled in parser, in the Identifier rule , ( "get", GetToken ) , ("set", SetToken ) {- Come from Table 6 of ECMASCRIPT 5.1, Attributes of a Named Accessor Property Also include Enumerable Configurable Table 7 includes Value -} -- Future Reserved Words , ( "class", FutureToken ) -- ("code", FutureToken ) **** not any more -- ("const", FutureToken ) **** an actual token, used in productions -- enum **** an actual token, used in productions , ( "export", FutureToken ) , ( "extends", FutureToken ) , ( "import", FutureToken ) , ( "super", FutureToken ) -- Strict mode FutureReservedWords , ( "implements", FutureToken ) , ( "interface", FutureToken ) , ( "let", FutureToken ) -- ("mode", FutureToken ) **** not any more -- ("of", FutureToken ) **** not any more -- ("one", FutureToken ) **** not any more -- ("or", FutureToken ) **** not any more , ( "package", FutureToken ) , ( "private", FutureToken ) , ( "protected", FutureToken ) , ( "public", FutureToken ) , ( "static", FutureToken ) -- ("strict", FutureToken ) *** not any more , ( "yield", FutureToken) ] } -- -- Edition 5.1 of ECMASCRIPT -- 7.6.1.1 Keywords -- The following tokens are ECMAScript keywords and may not be used as Identifiers in ECMAScript programs. -- Syntax -- Keyword :: one of -- break -- case -- catch -- continue -- debugger -- default -- delete -- do -- else -- finally -- for -- function -- if -- in -- instanceof -- new -- return -- switch -- this -- throw -- try -- typeof -- var -- void -- while -- with -- 7.6.1.2 Future Reserved Words -- The following words are used as keywords in proposed extensions and -- are therefore reserved to allow for the possibility of future adoption -- of those extensions. -- Syntax -- FutureReservedWord :: one of -- class -- const -- enum -- export -- extends -- import -- super -- The following tokens are also considered to be FutureReservedWords -- when they occur within strict mode code (see 10.1.1). The occurrence -- of any of these tokens within strict mode code in any context where -- the occurrence of a FutureReservedWord would produce an error must -- also produce an equivalent error: -- implements -- interface -- let -- package -- private -- protected -- public -- static -- yield -- Set emacs mode -- Local Variables: -- mode:haskell -- End: language-javascript-0.5.14.2/src/Language/JavaScript/Parser/Grammar5.y0000644000000000000000000016016012557503314023550 0ustar0000000000000000{ {-# LANGUAGE BangPatterns #-} module Language.JavaScript.Parser.Grammar5 ( parseProgram , parseLiteral , parsePrimaryExpression , parseStatement -- debug , fp ) where import Data.Char import Language.JavaScript.Parser.Lexer 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 {} } 'autosemi' { AutoSemiToken {} } '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. -- A MaybeSemi is an actual semi-colon or nothing. -- An AutoSemu is either an actual semi-colon or 'virtual' semi-colon inserted -- by the Alex lexer or nothing. MaybeSemi :: { AST.JSNode } MaybeSemi : ';' { AST.NT (AST.JSLiteral ";") (ss $1) (gc $1)} | { AST.NT (AST.JSLiteral "") tokenPosnEmpty []} AutoSemi :: { AST.JSNode } AutoSemi : ';' { AST.NT (AST.JSLiteral ";") (ss $1) (gc $1)} | '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 (tokenLiteral $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)) } -- ::= DecimalLiteral -- | HexIntegerLiteral -- | OctalLiteral NumericLiteral :: { AST.JSNode } NumericLiteral : 'decimal' { fp (AST.NT (AST.JSDecimal (tokenLiteral $1)) (ss $1) (gc $1))} | 'hexinteger' { fp (AST.NT (AST.JSHexInteger (tokenLiteral $1)) (ss $1) (gc $1)) } | 'octal' { fp (AST.NT (AST.JSOctal (tokenLiteral $1)) (ss $1) (gc $1)) } StringLiteral :: { AST.JSNode } StringLiteral : 'string' { fp (AST.NT (AST.JSStringLiteral (token_delimiter $1) (tokenLiteral $1)) (ss $1) (gc $1)) } -- ::= RegExp RegularExpressionLiteral :: { AST.JSNode } RegularExpressionLiteral : 'regex' { fp (AST.NT (AST.JSRegEx (tokenLiteral $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 (tokenLiteral $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 (tokenLiteral $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) )} -- ::= ':' -- | ',' ':' -- 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 MaybeSemi { fp (AST.NN (AST.JSVariables $1 $2 $3))} | Const VariableDeclarationList MaybeSemi { 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 MaybeSemi { fp (AST.NN (AST.JSDoWhile $1 $2 $3 $4 $5 $6 $7)) } | Do Expression MaybeSemi While LParen Expression RParen MaybeSemi { fp (AST.NN (AST.JSDoWhile $1 $2 $4 $5 $6 $7 $8)) } | 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 MaybeSemi { 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 MaybeSemi { 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 MaybeSemi { fp (AST.NN (AST.JSReturn $1 [$2] $3)) } -- WithStatement : See 12.10 -- with ( Expression ) Statement WithStatement :: { AST.JSNode } WithStatement : With LParen Expression RParen Statement MaybeSemi { 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' '(' Identifier ')' -- becomes -- ::= 'catch' '(' Identifier ')' -- | 'catch' '(' Identifier 'if' ConditionalExpression ')' 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' MaybeSemi { 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 tok = alexError (show tok) -- -------------------------------- ss :: Token -> TokenPosn ss = tokenSpan -- ------------------------------ gc :: Token -> [CommentAnnotation] gc = tokenComment mgc :: [Token] -> [CommentAnnotation] mgc xs = concatMap tokenComment xs -- --------------------------------------------------------------------- fp :: AST.JSNode -> AST.JSNode fp (AST.NN x) = (AST.NN x) fp (AST.NT x p cs) = (AST.NT x p cs) } language-javascript-0.5.14.2/src/Language/JavaScript/Pretty/0000755000000000000000000000000012557503314021732 5ustar0000000000000000language-javascript-0.5.14.2/src/Language/JavaScript/Pretty/Printer.hs0000644000000000000000000002071012557503314023711 0ustar0000000000000000module Language.JavaScript.Pretty.Printer ( -- * Printing renderJS , renderToString ) where import Data.Char import Data.List import Data.Monoid (Monoid, mappend, mempty) import Language.JavaScript.Parser.AST import Language.JavaScript.Parser.Parser import Language.JavaScript.Parser.SrcLocation import Language.JavaScript.Parser.Token import qualified Blaze.ByteString.Builder as BB import qualified Blaze.ByteString.Builder.Char.Utf8 as BS import qualified Data.ByteString.Lazy as LB import qualified Codec.Binary.UTF8.String as US -- --------------------------------------------------------------------- data Foo = Foo (Int,Int) BB.Builder -- --------------------------------------------------------------------- -- Pretty printer stuff via blaze-builder (<>) :: BB.Builder -> BB.Builder -> BB.Builder (<>) a b = mappend a b -- (<+>) :: BB.Builder -> BB.Builder -> BB.Builder -- (<+>) a b = mconcat [a, (text " "), b] --() ((Int, Int), BB.Builder) -> ((Int, Int), BB.Builder) -> ((Int, Int), BB.Builder) --() a b = -- hcat :: (Monoid a) => [a] -> a -- hcat xs = mconcat xs empty :: BB.Builder empty = mempty text :: String -> BB.Builder text s = BS.fromString s -- char :: Char -> BB.Builder -- char c = BS.fromChar c -- comma :: BB.Builder -- comma = BS.fromChar ',' -- punctuate :: a -> [a] -> [a] -- punctuate p xs = intersperse p xs -- --------------------------------------------------------------------- renderJS :: JSNode -> BB.Builder renderJS node = bb where Foo _ bb = rn node (Foo (1,1) empty) -- Take in the current -- rn :: (Int, Int) -> JSNode -> ((Int, Int), BB.Builder) rn :: JSNode -> Foo -> Foo -- Terminals rn (NT (JSIdentifier s ) p cs) foo = rcs cs p s foo rn (NT (JSDecimal i ) p cs) foo = rcs cs p i foo rn (NT (JSLiteral l ) p cs) foo = rcs cs p l foo rn (NT (JSHexInteger i ) p cs) foo = rcs cs p i foo rn (NT (JSOctal i ) p cs) foo = rcs cs p i foo rn (NT (JSStringLiteral s l) p cs) foo = rcs cs p ((s:l)++[s]) foo rn (NT (JSRegEx s ) p cs) foo = rcs cs p s foo -- Non-Terminals rn (NN (JSArguments lb xs rb)) foo = rJS ([lb] ++ xs ++ [rb]) foo rn (NN (JSArrayLiteral lb xs rb)) foo = rJS ([lb] ++ xs ++ [rb]) foo rn (NN (JSBlock lb x rb)) foo = rJS (lb ++ x ++ rb) foo rn (NN (JSBreak b x1s as)) foo = rJS ([b]++x1s++[as]) foo rn (NN (JSCallExpression _s os xs cs)) foo = rJS (os ++ xs ++ cs) foo rn (NN (JSCase ca x1 c x2s)) foo = rJS ([ca,x1,c]++x2s) foo rn (NN (JSCatch c lb x1 x2s rb x3)) foo = rJS ([c,lb,x1]++x2s++[rb,x3]) foo rn (NN (JSContinue c xs as)) foo = rJS ([c]++xs++[as]) foo rn (NN (JSDefault d c xs)) foo = rJS ([d,c]++xs) foo rn (NN (JSDoWhile d x1 w lb x2 rb x3)) foo = rJS ([d,x1,w,lb,x2,rb,x3]) foo rn (NN (JSElision c)) foo = rJS [c] foo rn (NN (JSExpression xs)) foo = rJS xs foo rn (NN (JSExpressionBinary _s lhs op rhs)) foo = rJS (lhs ++ [op] ++ rhs) foo rn (NN (JSExpressionParen lb e rb)) foo = rJS ([lb,e,rb]) foo rn (NN (JSExpressionPostfix _s xs op)) foo = rJS (xs ++ [op]) foo rn (NN (JSExpressionTernary cond h v1 c v2)) foo = rJS (cond ++[h] ++ v1 ++ [c] ++ v2) foo rn (NN (JSFinally f x)) foo = rJS [f,x] foo rn (NN (JSFor f lb x1s s1 x2s s2 x3s rb x4)) foo = rJS ([f,lb]++x1s++[s1]++x2s++[s2]++x3s++[rb,x4]) foo rn (NN (JSForIn f lb x1s i x2 rb x3)) foo = rJS ([f,lb]++x1s++[i,x2,rb,x3]) foo rn (NN (JSForVar f lb v x1s s1 x2s s2 x3s rb x4)) foo = rJS ([f,lb,v]++x1s++[s1]++x2s++[s2]++x3s++[rb,x4]) foo rn (NN (JSForVarIn f lb v x1 i x2 rb x3)) foo = rJS [f,lb,v,x1,i,x2,rb,x3] foo rn (NN (JSFunction f x1 lb x2s rb x3)) foo = rJS ([f,x1,lb]++x2s++[rb,x3]) foo -- rn (NN (JSFunctionBody xs)) foo = rJS xs foo rn (NN (JSFunctionExpression f x1s lb x2s rb x3)) foo = rJS ([f] ++ x1s ++ [lb] ++ x2s ++ [rb,x3]) foo rn (NN (JSIf i lb x1 rb x2s x3s)) foo = rJS ([i,lb,x1,rb]++x2s++x3s) foo rn (NN (JSLabelled l c v)) foo = rJS [l,c,v] foo rn (NN (JSMemberDot xs dot n)) foo = rJS (xs ++ [dot,n]) foo rn (NN (JSMemberSquare xs lb e rb)) foo = rJS (xs ++ [lb,e,rb]) foo rn (NN (JSObjectLiteral lb xs rb)) foo = rJS ([lb] ++ xs ++ [rb]) foo rn (NN (JSOperator n)) foo = rJS [n] foo rn (NN (JSPropertyAccessor s n lb1 ps rb1 b)) foo = rJS ([s,n,lb1] ++ ps ++ [rb1,b]) foo rn (NN (JSPropertyNameandValue n colon vs)) foo = rJS ([n,colon] ++ vs) foo rn (NN (JSReturn r xs as)) foo = rJS ([r] ++ xs ++ [as]) foo -- rn (NN (JSSourceElements xs)) foo = rJS xs foo rn (NN (JSSourceElementsTop xs)) foo = rJS xs foo -- rn (NN (JSStatementBlock lb x rb)) foo = rJS [lb,x,rb] foo -- rn (NN (JSStatementList xs)) foo = rJS xs foo rn (NN (JSSwitch s lb x rb x2)) foo = rJS ([s,lb,x,rb,x2]) foo rn (NN (JSThrow t x)) foo = rJS [t,x] foo rn (NN (JSTry t x1 x2s)) foo = rJS ([t,x1]++x2s) foo rn (NN (JSUnary _l n)) foo = rJS [n] foo rn (NN (JSVarDecl x1 x2s)) foo = rJS ([x1]++x2s) foo rn (NN (JSVariables n xs as)) foo = rJS ([n]++xs++[as]) foo rn (NN (JSWhile w lb x1 rb x2)) foo = rJS [w,lb,x1,rb,x2] foo rn (NN (JSWith w lb x1 rb x2s)) foo = rJS ([w,lb,x1,rb]++x2s) foo -- Debug helper rn what foo = rs (show what) foo --rn _ _ = undefined -- --------------------------------------------------------------------- -- Helper functions -- --------------------------------------------------------------------- -- Need a function that -- a) renders all comments, according to their positions -- b) advances to the position of the required string -- c) renders the string, advancing the position rcs :: [CommentAnnotation] -> TokenPosn -> String -> Foo -> Foo rcs cs p s foo = rps p s (rc cs foo) rc :: [CommentAnnotation] -> Foo -> Foo rc cs foo = foldl' go foo cs where go :: Foo -> CommentAnnotation -> Foo go bar NoComment = bar go bar (CommentA p s) = rps p s bar go bar (WhiteSpace p s) = rps p s bar -- Render a string at the given position rps :: TokenPosn -> String -> Foo -> Foo rps p s foo = (rs s foo') where foo' = (goto p foo) -- Render a string rs :: String -> Foo -> Foo rs s (Foo (r,c) bb) = (Foo (r',c') (bb <> (text s))) where (r',c') = foldl' (\(row,col) ch -> go (row,col) ch) (r,c) s go (r'',_) '\n' = (r''+1,1) go (r'',c'') '\t' = (r'',c''+8) go (r'',c'') _ = (r'',c''+1) goto :: TokenPosn -> Foo -> Foo goto (TokenPn _ ltgt ctgt) (Foo (lcur,ccur) bb) = (Foo (lnew,cnew) (bb <> bb')) -- goto (TokenPn _ ltgt ctgt) (Foo (lcur,ccur) bb) = trace ("goto " ++ (show $ (ltgt,ctgt)) ++ "," ++ (show $ (lcur,ccur)) ++ "," ++ (show $ (lnew,cnew)) ) $ (Foo (lnew,cnew) (bb <> bb')) where (bbline,ccur') = if (lcur < ltgt) then (text $ (take (ltgt - lcur) $ repeat '\n'),1) else (mempty,ccur) bbcol = if (ccur' < ctgt) then (text $ take (ctgt - ccur') $ repeat ' ' ) else mempty bb' = bbline <> bbcol lnew = if (lcur < ltgt) then ltgt else lcur cnew = if (ccur' < ctgt) then ctgt else ccur' rJS :: [JSNode] -> Foo -> Foo rJS xs foo = foldl' (flip rn) foo xs renderToString :: JSNode -> String -- need to be careful to not lose the unicode encoding on output renderToString js = US.decode $ LB.unpack $ BB.toLazyByteString $ renderJS js -- --------------------------------------------------------------------- -- Test stuff _r :: JSNode -> String _r js = map (\x -> chr (fromIntegral x)) $ LB.unpack $ BB.toLazyByteString $ renderJS js _t :: String -> String _t str = _r $ readJs str -- readJs "/*a*/x" _ax :: JSNode _ax = (NN (JSExpression [NT (JSIdentifier "x") (TokenPn 5 1 6) [CommentA (TokenPn 0 1 1) "/*a*/"]]) ) -- readJs "//j\nthis_" -- NS (JSSourceElementsTop [NS (JSExpression [NS (JSIdentifier "this_") (TokenPn 4 2 1) [CommentA (TokenPn 0 1 1) "//j"]]) (TokenPn 4 2 1) []]) (TokenPn 4 2 1) [] _r1 :: JSNode _r1 = NN ( JSExpression [ NT (JSIdentifier "this_") (TokenPn 4 2 1) [CommentA (TokenPn 0 1 1) "//j"] ]) -- EOF