├── .gitignore ├── .npmignore ├── .travis.yml ├── CHANGES ├── LICENSE ├── README.md ├── amdclean-node-globals.js ├── appveyor.yml ├── asyncSupport.js ├── bin ├── _boot_node.js ├── almond.js ├── jscc-browser.bat ├── jscc-browser.sh ├── jscc-nashorn.bat ├── jscc-nashorn.sh ├── jscc-node.bat ├── jscc-node.sh ├── jscc-rhino.bat ├── jscc-rhino.sh ├── runner-browser.js ├── runner-java.js ├── runner-node.js └── text.js ├── bower.json ├── code-style.xml ├── conf.json ├── doc ├── jscc_manual.odt └── jscc_manual.pdf ├── exports-require.js ├── exports-requireLib.js ├── exports.js ├── externs.js ├── fileoverview-node.js ├── fileoverview.js ├── global-backfills.js ├── gulpfile.js ├── lib └── jscc │ ├── bitset │ ├── BitSet32.js │ ├── BitSetBool.js │ ├── BitSetJava.js │ └── bitset.js │ ├── classes │ ├── Dfa.js │ ├── Item.js │ ├── Nfa.js │ ├── Param.js │ ├── Production.js │ ├── State.js │ ├── Symbol.js │ └── TableEntry.js │ ├── debug.js │ ├── enums │ ├── ASSOC.js │ ├── EDGE.js │ ├── EXEC.js │ ├── LOG_LEVEL.js │ ├── MODE_GEN.js │ ├── SPECIAL.js │ └── SYM.js │ ├── first.js │ ├── global.js │ ├── integrity.js │ ├── io │ ├── io.js │ ├── ioBrowser.js │ ├── ioNashorn.js │ ├── ioNode.js │ ├── ioRhino.js │ ├── ioSpiderMonkey.js │ └── ioV8.js │ ├── lexdbg.js │ ├── lexdfa.js │ ├── localHas.js │ ├── log │ ├── log.js │ ├── logBrowser.js │ ├── logJava.js │ └── logNode.js │ ├── main.js │ ├── nfaStates.js │ ├── parse.par │ ├── printtab.js │ ├── regex.par │ ├── tabgen.js │ ├── template │ └── parser-driver-js.txt │ └── util.js ├── main.js ├── npm-bin-template.js ├── package.json ├── require-browser-build.js ├── require-browser-config.js ├── require-main.js ├── require-nashorn-build.js ├── require-nashorn-config.js ├── require-node-build.js ├── require-node-config.js ├── require-rhino-build.js ├── require-rhino-config.js ├── resolvePackageDirectories.js ├── run-amdclean.js ├── samples ├── 99-bottles-of-beer.xpl ├── Makefile ├── calc_dotnet.par ├── calc_web.par ├── calc_wsh.par ├── countdown.xpl ├── hello.xpl ├── xpl.par └── xpl_opt.par ├── test ├── jscc.Test.js ├── jscc │ ├── integrity.Test.js │ ├── parse.Test.js │ ├── printtab.Test.js │ ├── regex.Test.js │ ├── tabgen.Test.js │ └── util.Test.js ├── runners.Test.js └── samples.Test.js ├── typedef.js ├── webenv ├── driver.js ├── img │ ├── back.png │ ├── e.png │ ├── l.png │ ├── la.png │ ├── ll.png │ ├── n.png │ ├── rn.png │ ├── t.png │ └── zoom.gif ├── jscc.css ├── jscc.html ├── jscc.js ├── jscc_logo.png ├── jscc_logo_small.png └── webdriver.js ├── wrap-end.js └── wrap-start.js /.gitignore: -------------------------------------------------------------------------------- 1 | /volo 2 | /converted_modules 3 | # Generated documentation 4 | /html-documentation 5 | 6 | # Build outputs 7 | jscc-*.js 8 | jscc-*.js.map 9 | /bin/jscc-node.js.map.old.map 10 | /bin/npm-*.js 11 | /samples/NashornProfile.txt 12 | /samples/output.js 13 | /externsWithRequire.js 14 | /lib/jscc/parse.js 15 | /lib/jscc/regex.js 16 | /coverage 17 | /.nyc_output 18 | *.lcov 19 | 20 | ### Windows template 21 | # Windows image file caches 22 | Thumbs.db 23 | /jar 24 | ehthumbs.db 25 | 26 | # Folder config file 27 | Desktop.ini 28 | 29 | # Recycle Bin used on file shares 30 | $RECYCLE.BIN/ 31 | 32 | # Windows Installer files 33 | *.cab 34 | *.msi 35 | *.msm 36 | *.msp 37 | 38 | # Windows shortcuts 39 | *.lnk 40 | ### Mercurial template 41 | /.hg/* 42 | */.hg/* 43 | .hgignore 44 | ### Node template 45 | # Logs 46 | logs 47 | *.log 48 | npm-debug.log* 49 | 50 | # Runtime data 51 | pids 52 | *.pid 53 | *.seed 54 | 55 | # Directory for instrumented libs generated by jscoverage/JSCover 56 | lib-cov 57 | 58 | # Coverage directory used by tools like istanbul 59 | coverage 60 | 61 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 62 | .grunt 63 | 64 | # node-waf configuration 65 | .lock-wscript 66 | 67 | # Compiled binary addons (http://nodejs.org/api/addons.html) 68 | build/Release 69 | 70 | # Dependency directory 71 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 72 | node_modules 73 | ### JetBrains template 74 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio 75 | 76 | *.iml 77 | 78 | ## Directory-based project format: 79 | .idea/ 80 | # if you remove the above rule, at least ignore the following: 81 | 82 | # User-specific stuff: 83 | # .idea/workspace.xml 84 | # .idea/tasks.xml 85 | # .idea/dictionaries 86 | 87 | # Sensitive or high-churn files: 88 | # .idea/dataSources.ids 89 | # .idea/dataSources.xml 90 | # .idea/sqlDataSources.xml 91 | # .idea/dynamic.xml 92 | # .idea/uiDesigner.xml 93 | 94 | # Gradle: 95 | # .idea/gradle.xml 96 | # .idea/libraries 97 | 98 | # Mongo Explorer plugin: 99 | # .idea/mongoSettings.xml 100 | 101 | ## File-based project format: 102 | *.ipr 103 | *.iws 104 | 105 | ## Plugin-specific files: 106 | 107 | # IntelliJ 108 | /out/ 109 | 110 | # mpeltonen/sbt-idea plugin 111 | .idea_modules/ 112 | 113 | # JIRA plugin 114 | atlassian-ide-plugin.xml 115 | 116 | # Crashlytics plugin (for Android Studio and IntelliJ) 117 | com_crashlytics_export_strings.xml 118 | crashlytics.properties 119 | crashlytics-build.properties 120 | ### Vim template 121 | [._]*.s[a-w][a-z] 122 | [._]s[a-w][a-z] 123 | *.un~ 124 | Session.vim 125 | .netrwhist 126 | *~ 127 | 128 | # Created by .ignore support plugin (hsz.mobi) 129 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Various directories and files that need not be in a published package 2 | /.nyc_output 3 | /converted_modules 4 | /coverage 5 | /samples 6 | /test 7 | /volo 8 | /webenv 9 | .travis.yml 10 | amdclean-node-globals.js 11 | asyncSupport.js 12 | code-style.xml 13 | conf.json 14 | exports*.js 15 | externs*.js 16 | fileoverview*.js 17 | global-backfills.js 18 | gulpfile.js 19 | npm-bin-template.js 20 | require-*-build.js 21 | require-*-config.js 22 | require-main.js 23 | resolvePackageDirectories.js 24 | run-amdclean.js 25 | typedef.js 26 | wrap-*.js 27 | *.lcov 28 | 29 | ### Windows template 30 | # Windows image file caches 31 | Thumbs.db 32 | /jar 33 | ehthumbs.db 34 | 35 | # Folder config file 36 | Desktop.ini 37 | 38 | # Recycle Bin used on file shares 39 | $RECYCLE.BIN/ 40 | 41 | # Windows Installer files 42 | *.cab 43 | *.msi 44 | *.msm 45 | *.msp 46 | 47 | # Windows shortcuts 48 | *.lnk 49 | ### Mercurial template 50 | /.hg/* 51 | */.hg/* 52 | .hgignore 53 | ### Node template 54 | # Logs 55 | logs 56 | *.log 57 | npm-debug.log* 58 | 59 | # Runtime data 60 | pids 61 | *.pid 62 | *.seed 63 | 64 | # Directory for instrumented libs generated by jscoverage/JSCover 65 | lib-cov 66 | 67 | # Coverage directory used by tools like istanbul 68 | coverage 69 | 70 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 71 | .grunt 72 | 73 | # node-waf configuration 74 | .lock-wscript 75 | 76 | # Compiled binary addons (http://nodejs.org/api/addons.html) 77 | build/Release 78 | 79 | # Dependency directory 80 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 81 | node_modules 82 | ### JetBrains template 83 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio 84 | 85 | *.iml 86 | 87 | ## Directory-based project format: 88 | .idea/ 89 | # if you remove the above rule, at least ignore the following: 90 | 91 | # User-specific stuff: 92 | # .idea/workspace.xml 93 | # .idea/tasks.xml 94 | # .idea/dictionaries 95 | 96 | # Sensitive or high-churn files: 97 | # .idea/dataSources.ids 98 | # .idea/dataSources.xml 99 | # .idea/sqlDataSources.xml 100 | # .idea/dynamic.xml 101 | # .idea/uiDesigner.xml 102 | 103 | # Gradle: 104 | # .idea/gradle.xml 105 | # .idea/libraries 106 | 107 | # Mongo Explorer plugin: 108 | # .idea/mongoSettings.xml 109 | 110 | ## File-based project format: 111 | *.ipr 112 | *.iws 113 | 114 | ## Plugin-specific files: 115 | 116 | # IntelliJ 117 | /out/ 118 | 119 | # mpeltonen/sbt-idea plugin 120 | .idea_modules/ 121 | 122 | # JIRA plugin 123 | atlassian-ide-plugin.xml 124 | 125 | # Crashlytics plugin (for Android Studio and IntelliJ) 126 | com_crashlytics_export_strings.xml 127 | crashlytics.properties 128 | crashlytics-build.properties 129 | ### Vim template 130 | [._]*.s[a-w][a-z] 131 | [._]s[a-w][a-z] 132 | *.un~ 133 | Session.vim 134 | .netrwhist 135 | *~ 136 | 137 | # Created by .ignore support plugin (hsz.mobi) 138 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | sudo: false 3 | node_js: 4 | - '6' 5 | - '4' 6 | env: 7 | global: 8 | - CXX=g++-4.8 9 | - GITHUB_API_USERNAME=abrobston 10 | - secure: JQike4USg7Kf8IIcNPKTmSZOUT0Qx7qMKiQh22LfHbQSFmcWGg30wTrqftsg6GI5OUu3z7ushlf+25I+eUGYBTyxB11j5dpSc6SZmylk5sCd5dtA/raAjasqqL9ZnldFh3u8BJfzeM2FJKY5GeovSXkGmF0aCctHyc1z6N7s0iE761EKtMioqU2CLbxE47Eh49qz92D8exIaQMmjXRGelJbOFX2W/1qWzCwg4PvXvuufhvGe4ckrwqvPBA+WWTq5+5ypR60/iMShwodCkhz05a0cHW6HtDH2EiKxPV+G51ItlnhTTPQjKbYFiCsu4+FH49zhyDXClBizLrrMqUb//Eo8dWMbZe7EXks7t867XZCkgGaYkcRDOKitEwFEewWpXZwtalzHk7ZVRd8agFxpe+OmpNSdKDfQfFZQI9l0C212I4Kc4etp+AqqP3Ujz7/ROoGEjdVrbWo1KMN2gmb9p/EL74TDDOd4aVeHPJjC4Ho1p/LpzbxPbBPNdfHOvsZwT7CHDR6WNnCE4EHzadYnjvxPQH4c2Ewz4b46zrHuRzfEk/OnhhfyfwDzyHlHnJjpuIkpAXeWqhPrtu9immoxhq3P7jl6iWX25fDPDVpQJpqJe8ki/9f8uTOXCpuApaJQ3nvzN0ByQAFXJr/q/JWaxV2fTrCohGdgBCvAVyMl0sw= 11 | matrix: 12 | - JAVA_HOME=/usr/lib/jvm/java-8-oracle 13 | - JAVA_HOME=/usr/lib/jvm/java-9-oracle 14 | matrix: 15 | exclude: 16 | - env: JAVA_HOME=/usr/lib/jvm/java-9-oracle 17 | node_js: '6' 18 | allow_failures: 19 | - env: JAVA_HOME=/usr/lib/jvm/java-9-oracle 20 | addons: 21 | apt: 22 | sources: 23 | - ubuntu-toolchain-r-test 24 | packages: 25 | - oracle-java8-installer 26 | - oracle-java9-installer 27 | - g++-4.8 28 | - python2.7 29 | - make 30 | before_install: 31 | - npm install -g node-gyp 32 | - npm config set python /usr/bin/python2.7 33 | install: 34 | - npm install 35 | script: npm test 36 | after_success: npm run coverage 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | JS/CC LALR(1) Parser Generator 2 | Copyright © 2007-2016 by Phorward Software Technologies; Jan Max Meyer; 3 | Brobston Development, Inc.; and other contributors 4 | http://jscc.brobston.com ++ contact<>phorward-software<>com 5 | -------------------------------------------------------------------------------- 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are 9 | met: 10 | 11 | 1. Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | 2. Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in the 15 | documentation and/or other materials provided with the 16 | distribution. 17 | 3. Neither the names of the copyright holders nor the 18 | names of their contributors may be used to endorse or promote 19 | products derived from this software without specific prior 20 | written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR 26 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 27 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 29 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 31 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/abrobston/jscc.svg?branch=master)](https://travis-ci.org/abrobston/jscc) 2 | [![Build Status](https://ci.appveyor.com/api/projects/status/gfedhmq6rliywmde/branch/master?svg=true)](https://ci.appveyor.com/project/abrobston/jscc/branch/master) 3 | [![codecov](https://codecov.io/gh/abrobston/jscc/branch/master/graph/badge.svg)](https://codecov.io/gh/abrobston/jscc) 4 | [![npm](https://img.shields.io/npm/v/jscc-parser.svg?maxAge=2592000)](https://www.npmjs.com/package/jscc-parser) 5 | 6 | JS/CC LALR(1) Parser Generator 7 | Copyright © 2007-2016 by Phorward Software Technologies; Jan Max Meyer; Brobston Development, Inc.; and other contributors 8 | http://jscc.brobston.com ++ contact<>phorward-software<>com 9 | 10 | INTRODUCTION 11 | ------------ 12 | 13 | 14 | JS/CC is the first available parser development system for JavaScript 15 | and ECMAScript-derivates. It has been developed, both, with the 16 | intention of building a productive compiler development system and 17 | with the intention of creating an easy-to-use academic environment for 18 | people interested in how parse table generation is done generally in 19 | bottom-up parsing. 20 | 21 | JS/CC brings a lex/yacc-like toolchain into the world of ECMAScript. 22 | 23 | LICENSE 24 | ------- 25 | 26 | JS/CC is initially written by Jan Max Meyer (Phorward Software Technologies) 27 | with contributions by Louis P. Santillan and Sergiy Shatunov. Work 28 | to migrate JS/CC to GitHub, add modularity, and package for npm and Bower 29 | was done by Andrew Brobston. JS/CC is released under the terms and 30 | conditions of the 3-clause BSD license. 31 | 32 | REQUIREMENTS 33 | ------------ 34 | 35 | To use JS/CC, you need either Mozilla/Rhino, Node.js, Nashorn, or an 36 | ordinary ECMAScript compatible web browser! Versions through 0.37.0 37 | supported Mozilla/Spidermonkey, Google V8, and Microsoft JScript. 38 | If resumed support for these platforms is desired, pull requests are welcome. 39 | 40 | The build system uses Gulp. Google's Closure Compiler is used for verifying 41 | and minifying the code for the various platforms. Code contributions should 42 | ensure that all tests pass (using the Mocha framework, with the TDD code style 43 | and Chai assertion library) and that there are no Closure Compiler warnings 44 | or errors. 45 | 46 | The npm package is named `jscc-parser`, as `jscc` was already taken. 47 | 48 | ABOUT 49 | ----- 50 | 51 | JS/CC is a platform-independent software that unions both: A regular 52 | expression-based lexical analyzer generator matching individual tokens from 53 | the input character stream and a LALR(1) parser generator, computing the parse 54 | tables for a given context-free grammar specification to build a stand-alone, 55 | working parser. The context-free grammar fed to JS/CC is defined in a 56 | Backus-Naur-Form-based meta language, and allows the insertion of individual 57 | semantic code to be evaluated on a rule's reduction. JS/CC itself has been 58 | entirely written in JavaScript so it can be executed in many different ways: 59 | as platform-independent, browser-based JavaScript embedded on a Website, as 60 | as a Mozilla/Rhino or Java Nashorn interpreted application, or a 61 | Node shell script on Windows, *nix, Linux and Mac OSX. However, for productive 62 | execution, it is recommended to use the command-line versions. 63 | These versions are capable of assembling a complete compiler from a JS/CC 64 | parser specification, which is then stored to a .js JavaScript source file. 65 | 66 | To use JS/CC and for understanding its internals and behavior, some knowledge 67 | of context-free grammars, bottom-up parsing techniques and compiler 68 | construction theory, in general, is assumed. 69 | 70 | BUILDING 71 | -------- 72 | 73 | 1. Ensure that you have Node.js and npm. See 74 | https://docs.npmjs.com/getting-started/installing-node for details. 75 | Building and testing JS/CC most recently used Node versions 4.4.7 76 | and 6.3.1, but other versions will likely work also. 77 | 2. Ensure that you have Gulp version 3.x. See 78 | https://github.com/gulpjs/gulp/blob/master/docs/getting-started.md. 79 | Gulp version 4.x may work but has not been tested. 80 | 3. Ensure that Java 8 or later is installed and that the `JAVA_HOME` 81 | environment variable points to the correct path of this installation. 82 | Builds and tests have been done with Oracle's distribution of 83 | Java 8. OpenJDK 8 may work but has not been tested. 84 | 4. From the root project directory, run `npm update`. 85 | 5. To run the default build target, simply run `gulp`. The default 86 | build target downloads some additional dependencies, generates 87 | documentation, and builds for the four platforms currently 88 | supported. To run Mocha tests, first build with `gulp`, then 89 | run `gulp test`. For other targets, see gulpfile.js. 90 | 91 | USE 92 | --- 93 | 94 | JS/CC can be used as a JavaScript module or with one of the command-line runners. 95 | 96 | ### As a Module 97 | 98 | After `var jscc = require("jscc-parser")` or equivalent, call the `jscc` function with an object containing options: 99 | 100 | | Option | Type | Default | Description | 101 | | ------ | ---- | ------- | ----------- | 102 | | `out_file` | `string` | Empty string, meaning to print to standard output or the engine's equivalent | The path of the output file. | 103 | | `src_file` | `string` | Empty string, meaning to read from standard input or the engine's equivalent. | The path of the input grammar file. | 104 | | `tpl_file` | `string` | A default template file for generic compilation tasks. | The path of the input template file. | 105 | | `input` | `string` or `function` | None | If a string, the contents of the input grammar. If a function, a function that returns the contents of the grammar. When `input` is specified, `src_file` is ignored. | 106 | | `template` | `string` or `function` | None | If a string, the contents of the template. If a function with no arguments, a function that returns the contents of the template. When `template` is specified, `tpl_file` is ignored. | 107 | | `outputCallback` | `function(string)` | None | A function with a parameter that will be called with the output. When `outputCallback` is specified, `out_file` is ignored. | 108 | | `dump_nfa` | `boolean` | `false` | Whether to output the nondeterministic finite automata for debugging purposes. | 109 | | `dump_dfa` | `boolean` | `false` | Whether to output the deterministic finite automata for debugging purposes. | 110 | | `verbose` | `boolean` | `false` | Makes output slightly chattier. Will probably be deprecated in favor of using only `logLevel` at some point. | 111 | | `logLevel` | `string` or member of the `jscc.enums.LOG_LEVEL` enumeration (`FATAL`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`) | `WARN` | The logging level. | 112 | | `throwIfErrors` | `boolean` | `false` | Whether to throw an exception before completion of the main method if there are any compilation errors. | 113 | | `exitIfErrors` | `boolean` | `false` | Whether to exit the process with a non-zero exit code if there are any errors, provided that the platform permits doing so. Intended for use with shell scripts. | 114 | 115 | ### From the Command Line 116 | 117 | After building JS/CC, the `bin` directory should contain shell scripts for both *nix 118 | and Windows. There are scripts for each platform. For example, to run using the 119 | Nashorn engine on Linux: 120 | 121 | ./bin/jscc-nashorn.sh --src_file "./path/to/src" --out_file "./path/to/output" --logLevel INFO 122 | 123 | The `throwIfErrors` and `exitIfErrors` options are not supported from the command line because 124 | each runner sets those options according to its needs. 125 | 126 | GRAMMAR FILES 127 | ------------- 128 | 129 | See the [online documentation](http://jscc.brobston.com/documentation/grammar/general.html) for information 130 | on the grammar file syntax that JS/CC requires. 131 | -------------------------------------------------------------------------------- /amdclean-node-globals.js: -------------------------------------------------------------------------------- 1 | //amdclean 2 | /** @suppress {duplicate} */ 3 | var util = require("util"); 4 | /** @suppress {duplicate} */ 5 | var fs = require("fs"); 6 | /** @suppress {duplicate} */ 7 | var path = require("path"); -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | branches: 2 | except: 3 | - gh-pages 4 | 5 | environment: 6 | global: 7 | JAVA_HOME: C:\Program Files\Java\jdk1.8.0 8 | GITHUB_API_USERNAME: abrobston 9 | GITHUB_API_PASSWORD: 10 | secure: n00Pw0lfVdSJjCOVrIEaDJF4tenjfN/6GrXmUTuYuaNiJIotoH3pasVJ8Foqel6P 11 | matrix: 12 | - nodejs_version: "4" 13 | - nodejs_version: "6" 14 | 15 | install: 16 | - ps: Install-Product node $env:nodejs_version 17 | - cmd: npm install 18 | 19 | build: off 20 | 21 | test_script: 22 | - npm test 23 | 24 | on_success: 25 | - npm run coverage 26 | -------------------------------------------------------------------------------- /bin/jscc-browser.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | SETLOCAL 3 | REM Use PhantomJS from npm (the phantomjs-prebuilt package), but use the standalone 4 | REM (non-Node) executable 5 | SET _search_dir=%~dp0\..\node_modules\phantomjs-prebuilt 6 | SET _phantom_path=none 7 | FOR /F "delims=`" %%g IN ('DIR "%_search_dir%" /S /A:-D /O:D /b ^| FINDSTR /I "phantomjs\.exe$"') DO IF "%_phantom_path%"=="none" SET _phantom_path=%%g 8 | IF "%_phantom_path%"=="none" ( 9 | ECHO "phantomjs.exe was not found in any subdirectory of %_search_dir%" 10 | EXIT 1 11 | ) 12 | "%_phantom_path%" "%~dp0\runner-browser.js" %* 13 | EXIT %ERRORLEVEL% 14 | ENDLOCAL -------------------------------------------------------------------------------- /bin/jscc-browser.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Use PhantomJS from npm (the phantomjs-prebuilt package), but use the standalone 4 | # (non-Node) executable 5 | nodeExe=$(which nodejs || which node) 6 | searchDir=$(dirname $0)/../node_modules/phantomjs-prebuilt 7 | env=$(which env) 8 | if [ -r "${searchDir}/lib/location.js" ] 9 | then 10 | phantomPath=$(grep "module.exports.location" "${searchDir}/lib/location.js" | sed -re 's/^.*=\s*"(.*)"\s*$/\1/') 11 | if [[ "${phantomPath}" =~ ^[^/] ]] 12 | then 13 | phantomPath=${searchDir}/lib/${phantomPath} 14 | fi 15 | else 16 | if [ "${npm_config_tmp}x" = "x" ] 17 | then 18 | npm_config_tmp=$(dirname $0)/../tmp 19 | fi 20 | ${env} npm_config_tmp=${npm_config_tmp} ${nodeExe} ${searchDir}/install.js 21 | phantomPath=${searchDir}/lib/$(grep "module.exports.location" ${searchDir}/lib/location.js | sed -re 's/^.*=\s*"(.*)"\s*$/\1/') 22 | fi 23 | 24 | if [ -x "${phantomPath}" ] 25 | then 26 | "${phantomPath}" "$(dirname $0)/runner-browser.js" "$@" 27 | exit $? 28 | else 29 | echo "The phantomjs executable was not found (or was not executable) at '${phantomPath}'" 30 | exit 1 31 | fi 32 | -------------------------------------------------------------------------------- /bin/jscc-nashorn.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | SETLOCAL 3 | SET _jjs=%JAVA_HOME%\bin\jjs.exe 4 | IF NOT EXIST "%_jjs%" ( 5 | ECHO "Nashorn executable not found at %_jjs%. Ensure that the JAVA_HOME environment variable points to the root of a Java 8 or later installation." 6 | EXIT 1 7 | ) 8 | "%_jjs%" -doe --debug-locals=true --debug-lines=true "%~dp0\runner-java.js" -- """%~dp0"" nashorn %*" 9 | EXIT %ERRORLEVEL% 10 | ENDLOCAL 11 | -------------------------------------------------------------------------------- /bin/jscc-nashorn.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | jjs=${JAVA_HOME}/bin/jjs 3 | dirname=$(dirname $0) 4 | if [ -x "$jjs" ] 5 | then 6 | "${jjs}" -doe --debug-locals=true --debug-lines=true "${dirname}/runner-java.js" -- "${dirname}" nashorn "$@" 7 | exit $? 8 | else 9 | echo "Nashorn executable not found at '${jjs}' or is not executable. Ensure that the JAVA_HOME environment variable points to the root of a Java 8 or later installation." 10 | exit 1 11 | fi 12 | -------------------------------------------------------------------------------- /bin/jscc-node.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | node.exe "%~dp0\runner-node.js" %* -------------------------------------------------------------------------------- /bin/jscc-node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | nodeExe=$(which nodejs || which node) 3 | if [ -x "${nodeExe}" ] 4 | then 5 | "${nodeExe}" "$(dirname $0)/runner-node.js" "$@" 6 | exit $? 7 | else 8 | echo "Could not find node executable in PATH" 9 | exit 1 10 | fi 11 | -------------------------------------------------------------------------------- /bin/jscc-rhino.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | SETLOCAL 3 | REM Find the Rhino executable 4 | SET _jar_dir=%~dp0\..\jar 5 | SET _rhino_path=none 6 | FOR /F "delims=`" %%g IN ('DIR "%_jar_dir%" /S /A:-D /O:D /b ^| FINDSTR /I "rhino[^\\]*\.jar$"') DO IF "%_rhino_path%"=="none" SET _rhino_path=%%g 7 | IF "%_rhino_path%"=="none" ( 8 | ECHO "rhino*.jar was not found in any subdirectory of %_jar_dir%" 9 | EXIT 1 10 | ) 11 | "%JAVA_HOME%\bin\java.exe" -server -XX:+TieredCompilation -classpath "%_rhino_path%" org.mozilla.javascript.tools.shell.Main -opt -1 "%~dp0\runner-java.js" """%~dp0"" rhino %*" 12 | EXIT %ERRORLEVEL% 13 | ENDLOCAL -------------------------------------------------------------------------------- /bin/jscc-rhino.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | dirname=$(dirname $0) 3 | jarDir=${dirname}/../jar 4 | javaPath=${JAVA_HOME}/bin/java 5 | if [ ! -x "${javaPath}" ] 6 | then 7 | echo "Java executable not found. Ensure that JAVA_HOME is set correctly." 8 | exit 1 9 | fi 10 | 11 | rhinoPath=$(find "${jarDir}" -iname 'rhino*.jar' | head -n 1) 12 | 13 | if [ -r "${rhinoPath}" ] 14 | then 15 | "${javaPath}" -server -XX:+TieredCompilation -classpath "${rhinoPath}" org.mozilla.javascript.tools.shell.Main -opt -1 "${dirname}/runner-java.js" "${dirname}" rhino "$@" 16 | exit $? 17 | else 18 | echo "Rhino jar file not found in '${jarDir}' or its subdirectories." 19 | exit 1 20 | fi 21 | -------------------------------------------------------------------------------- /bin/runner-browser.js: -------------------------------------------------------------------------------- 1 | var innerErrorMessage = null, innerErrorTrace = []; 2 | function dumpObject(obj) { 3 | if (typeof obj === "string") { 4 | console.log(obj); 5 | } else { 6 | for (var current in obj) { 7 | console.log("" + current + ": " + obj[current]); 8 | } 9 | } 10 | } 11 | 12 | function onError(msg, trace) { 13 | var msgStack = ["PHANTOM ERROR:"]; 14 | if (msg) { 15 | msgStack.push(msg); 16 | if (trace && trace.length) { 17 | innerErrorTrace = trace; 18 | msgStack.push("TRACE:"); 19 | for (var index = 0; index < trace.length; index++) { 20 | var current = trace[index]; 21 | msgStack.push(" -> " + (current.file || current.sourceURL) + ": " + current.line + (current.function ? " (in function " + current.function + ")" : "")); 22 | } 23 | } 24 | } 25 | innerErrorMessage = msgStack.join("\n"); 26 | console.error(innerErrorMessage); 27 | phantom.exit(1); 28 | } 29 | 30 | try { 31 | var system = require("system"); 32 | var fs = require("fs"); 33 | var args = system.args; 34 | var possibleOptions = { 35 | "out_file": "string", 36 | "src_file": "string", 37 | "tpl_file": "string", 38 | "dump_nfa": "boolean", 39 | "dump_dfa": "boolean", 40 | "verbose": "boolean", 41 | "input": "string", 42 | "template": "string", 43 | "logLevel": "LOG_LEVEL" 44 | }; 45 | var options = { 46 | throwIfErrors: true 47 | }; 48 | var argLength = args.length; 49 | var onDeck = ""; 50 | var nextIsLogLevel = false; 51 | for (var index = 1; index < argLength; index++) { 52 | if (onDeck === "") { 53 | var optMatch = /^(--|\/)([a-zA-Z0-9_]+)$/.exec(args[index]); 54 | if (optMatch !== null) { 55 | var optName = optMatch[2]; 56 | if (possibleOptions.hasOwnProperty(optName)) { 57 | if (options.hasOwnProperty(optName)) { 58 | throw new Error("Duplicate option: " + optName); 59 | } 60 | var optType = possibleOptions[optName]; 61 | switch (optType) { 62 | case "boolean": 63 | options[optName] = true; 64 | break; 65 | case "LOG_LEVEL": 66 | onDeck = optName; 67 | nextIsLogLevel = true; 68 | break; 69 | case "string": 70 | onDeck = optName; 71 | break; 72 | default: 73 | throw new Error("Invalid option: " + optName); 74 | break; 75 | } 76 | } 77 | } else if (!options.hasOwnProperty("src_file")) { 78 | options["src_file"] = args[index]; 79 | } else { 80 | throw new Error("Extra command-line argument: " + args[index]); 81 | } 82 | } else if (nextIsLogLevel) { 83 | var logLevelName = args[index].toUpperCase(); 84 | switch (logLevelName) { 85 | case "FATAL": 86 | case "ERROR": 87 | case "WARN": 88 | case "INFO": 89 | case "DEBUG": 90 | case "TRACE": 91 | options[onDeck] = logLevelName; 92 | nextIsLogLevel = false; 93 | onDeck = ""; 94 | break; 95 | case "WARNING": 96 | options[onDeck] = "WARN"; 97 | nextIsLogLevel = false; 98 | onDeck = ""; 99 | break; 100 | case "ALL": 101 | options[onDeck] = "TRACE"; 102 | nextIsLogLevel = false; 103 | onDeck = ""; 104 | break; 105 | default: 106 | throw new Error("Invalid log level: " + args[index]); 107 | break; 108 | } 109 | } else { 110 | options[onDeck] = args[index]; 111 | onDeck = ""; 112 | } 113 | } 114 | 115 | if (onDeck !== "") { 116 | throw new Error("No value specified for option: " + onDeck); 117 | } 118 | 119 | if (options.hasOwnProperty("out_file")) { 120 | var outFile = options["out_file"]; 121 | delete options["out_file"]; 122 | options.outputCallback = (function(out) { 123 | return function(contents) { 124 | try { 125 | fs.write(out, contents, { mode: "w", charset: "utf-8" }); 126 | } catch (e) { 127 | if (typeof e === "string") { 128 | console.log(e); 129 | throw new Error(e); 130 | } 131 | throw e; 132 | } 133 | }; 134 | })(outFile); 135 | } 136 | 137 | if (options.hasOwnProperty("src_file")) { 138 | var srcFile = options["src_file"]; 139 | delete options["src_file"]; 140 | options.input = (function(src) { 141 | return function() { 142 | try { 143 | return fs.read(src, { mode: "r", charset: "utf-8" }); 144 | } catch (e) { 145 | if (typeof e === "string") { 146 | console.log(e); 147 | throw new Error(e); 148 | } 149 | throw e; 150 | } 151 | }; 152 | })(srcFile); 153 | } 154 | 155 | if (options.hasOwnProperty("tpl_file")) { 156 | var tplFile = options["tpl_file"]; 157 | delete options["tpl_file"]; 158 | options.template = (function(tpl) { 159 | return function() { 160 | try { 161 | return fs.read(tpl, { mode: "r", charset: "utf-8" }); 162 | } catch (e) { 163 | if (typeof e === "string") { 164 | console.log(e); 165 | throw new Error(e); 166 | } 167 | throw e; 168 | } 169 | }; 170 | })(tplFile); 171 | } 172 | 173 | phantom.onError = onError; 174 | var jsccPath = phantom.libraryPath + fs.separator + "jscc-browser.js"; 175 | phantom.injectJs(jsccPath); 176 | var jscc = requireLib("main"); 177 | jscc(options); 178 | if (innerErrorMessage) { 179 | throw new Error(innerErrorMessage); 180 | } 181 | phantom.exit(0); 182 | } catch (e) { 183 | dumpObject(e); 184 | phantom.exit(1); 185 | } 186 | -------------------------------------------------------------------------------- /bin/runner-java.js: -------------------------------------------------------------------------------- 1 | function stripQuotes (input) { 2 | // Argument quoting, at least from Windows, has some issues. Strip quotes 3 | // from the arguments if needed. 4 | var match = /^"(.*)"$/.exec(input); 5 | return match ? match[1] : input; 6 | } 7 | 8 | var args = arguments; 9 | var currentDirectory = stripQuotes(args[0]); 10 | var runnerName = stripQuotes(args[1]); 11 | var possibleOptions = { 12 | "out_file": "string", 13 | "src_file": "string", 14 | "tpl_file": "string", 15 | "dump_nfa": "boolean", 16 | "dump_dfa": "boolean", 17 | "verbose": "boolean", 18 | "input": "string", 19 | "template": "string", 20 | "logLevel": "LOG_LEVEL" 21 | }; 22 | var options = { 23 | throwIfErrors: true 24 | }; 25 | var argLength = args.length; 26 | var onDeck = ""; 27 | var nextIsLogLevel = false; 28 | for (var index = 2; index < argLength; index++) { 29 | if (onDeck === "") { 30 | var optMatch = /^(--|\/)([a-zA-Z0-9_]+)$/.exec(args[index]); 31 | if (optMatch !== null) { 32 | var optName = optMatch[2]; 33 | if (possibleOptions.hasOwnProperty(optName)) { 34 | if (options.hasOwnProperty(optName)) { 35 | java.lang.System.err.println("Duplicate option: " + optName); 36 | quit(1); 37 | } 38 | var optType = possibleOptions[optName]; 39 | switch (optType) { 40 | case "boolean": 41 | options[optName] = true; 42 | break; 43 | case "LOG_LEVEL": 44 | onDeck = optName; 45 | nextIsLogLevel = true; 46 | break; 47 | case "string": 48 | onDeck = optName; 49 | break; 50 | default: 51 | java.lang.System.err.println("Invalid option: " + optName); 52 | quit(1); 53 | break; 54 | } 55 | } 56 | } else if (!options.hasOwnProperty("src_file")) { 57 | options["src_file"] = stripQuotes(args[index]); 58 | } else { 59 | java.lang.System.err.println("Extra command-line argument: " + args[index]); 60 | quit(1); 61 | } 62 | } else if (nextIsLogLevel) { 63 | var logLevelName = args[index].toUpperCase(); 64 | switch (logLevelName) { 65 | case "FATAL": 66 | case "ERROR": 67 | case "WARN": 68 | case "INFO": 69 | case "DEBUG": 70 | case "TRACE": 71 | options[onDeck] = logLevelName; 72 | nextIsLogLevel = false; 73 | onDeck = ""; 74 | break; 75 | case "WARNING": 76 | options[onDeck] = "WARN"; 77 | nextIsLogLevel = false; 78 | onDeck = ""; 79 | break; 80 | case "ALL": 81 | options[onDeck] = "TRACE"; 82 | nextIsLogLevel = false; 83 | onDeck = ""; 84 | break; 85 | default: 86 | java.lang.System.err.println("Invalid log level: " + args[index]); 87 | quit(1); 88 | break; 89 | } 90 | } else { 91 | options[onDeck] = stripQuotes(args[index]); 92 | onDeck = ""; 93 | } 94 | } 95 | 96 | if (onDeck !== "") { 97 | java.lang.System.err.println("No value specified for option: " + onDeck); 98 | quit(1); 99 | } 100 | 101 | var jsccPath = java.nio.file.Paths.get(currentDirectory, "jscc-" + runnerName + ".js").toAbsolutePath().toString(); 102 | 103 | load(jsccPath); 104 | var jscc = require("main"); 105 | try { 106 | jscc(options); 107 | } catch (e) { 108 | java.lang.System.err.println("Uncaught error: " + e); 109 | quit(1); 110 | } 111 | quit(0); 112 | -------------------------------------------------------------------------------- /bin/runner-node.js: -------------------------------------------------------------------------------- 1 | var jscc = require('./jscc-node'); 2 | var possibleOptions = { 3 | "out_file": "string", 4 | "src_file": "string", 5 | "tpl_file": "string", 6 | "dump_nfa": "boolean", 7 | "dump_dfa": "boolean", 8 | "verbose": "boolean", 9 | "input": "string", 10 | "template": "string", 11 | "logLevel": "LOG_LEVEL" 12 | }; 13 | var options = { 14 | exitIfErrors: true 15 | }; 16 | var argLength = process.argv.length; 17 | var onDeck = ""; 18 | var nextIsLogLevel = false; 19 | for (var index = 2; index < argLength; index++) { 20 | if (onDeck === "") { 21 | var optMatch = /^(--|\/)([a-zA-Z0-9_]+)$/.exec(process.argv[index]); 22 | if (optMatch !== null) { 23 | var optName = optMatch[2]; 24 | if (possibleOptions.hasOwnProperty(optName)) { 25 | if (options.hasOwnProperty(optName)) { 26 | console.error("Duplicate option: " + optName); 27 | process.exit(1); 28 | } 29 | var optType = possibleOptions[optName]; 30 | switch (optType) { 31 | case "boolean": 32 | options[optName] = true; 33 | break; 34 | case "LOG_LEVEL": 35 | onDeck = optName; 36 | nextIsLogLevel = true; 37 | break; 38 | case "string": 39 | onDeck = optName; 40 | break; 41 | default: 42 | console.error("Invalid option: " + optName); 43 | process.exit(1); 44 | break; 45 | } 46 | } 47 | } else if (!options.hasOwnProperty("src_file")) { 48 | options["src_file"] = process.argv[index]; 49 | } else { 50 | console.error("Extra command-line argument: " + process.argv[index]); 51 | process.exit(1); 52 | } 53 | } else if (nextIsLogLevel) { 54 | var logLevelName = process.argv[index].toUpperCase(); 55 | switch (logLevelName) { 56 | case "FATAL": 57 | case "ERROR": 58 | case "WARN": 59 | case "INFO": 60 | case "DEBUG": 61 | case "TRACE": 62 | options[onDeck] = logLevelName; 63 | nextIsLogLevel = false; 64 | onDeck = ""; 65 | break; 66 | case "WARNING": 67 | options[onDeck] = "WARN"; 68 | nextIsLogLevel = false; 69 | onDeck = ""; 70 | break; 71 | case "ALL": 72 | options[onDeck] = "TRACE"; 73 | nextIsLogLevel = false; 74 | onDeck = ""; 75 | break; 76 | default: 77 | console.error("Invalid log level: " + process.argv[index]); 78 | process.exit(1); 79 | break; 80 | } 81 | } else { 82 | options[onDeck] = process.argv[index]; 83 | onDeck = ""; 84 | } 85 | } 86 | 87 | if (onDeck !== "") { 88 | console.error("No value specified for option: " + onDeck); 89 | process.exit(1); 90 | } 91 | 92 | //jscc.jscc(options); 93 | jscc.main(options); 94 | process.exit(0); 95 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jscc", 3 | "description": "A LALR(1) Parser for JavaScript written in JavaScript", 4 | "main": "lib/jscc.js", 5 | "moduleType": ["amd", "node", "globals"], 6 | "keywords": ["lexer", "parser", "lex", "yacc", "lexical-analysis"], 7 | "authors": ["Jan Max Meyer (http://jscc.phorward-software.com/)", 8 | "Sergiy Shatunov", 9 | "Louis P. Santillan", 10 | "Andrew Brobston "], 11 | "homepage": "http://jscc.phorward-software.com/", 12 | "repository": {"type": "git", "url": "https://github.com/abrobston/jscc.git"}, 13 | "license": "BSD-3-Clause", 14 | "ignore": [ 15 | "/samples", 16 | "/test", 17 | "/webenv", 18 | ".travis.yml", 19 | "code-style.xml", 20 | "conf.json", 21 | "exports*.js", 22 | "externs*.js", 23 | "fileoverview*.js", 24 | "global-backfills.js", 25 | "gulpfile.js", 26 | "require-*-build.js", 27 | "require-*-config.js", 28 | "run-amdclean.js", 29 | "typedef.js", 30 | "wrap-*.js", 31 | "/jar", 32 | "*.log", 33 | "*.iml", 34 | ".idea/", 35 | "[._]*.s[a-w][a-z]", 36 | "[._]s[a-w][a-z]", 37 | "*.un~", 38 | "Session.vim", 39 | ".netrwhist", 40 | "*~" 41 | ] 42 | } -------------------------------------------------------------------------------- /code-style.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 9 | 10 | 29 | -------------------------------------------------------------------------------- /conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": { 3 | "allowUnknownTags": true, 4 | "dictionaries": ["closure", "jsdoc"] 5 | }, 6 | "source": { 7 | "include": "./lib/jscc", 8 | "includePattern": ".+\\.js(doc)?$", 9 | "excludePattern": "(^|\\/|\\\\)_" 10 | }, 11 | "plugins": [], 12 | "templates": { 13 | "cleverLinks": false, 14 | "monospaceLinks": false 15 | }, 16 | "opts": { 17 | "recurse": true, 18 | "destination": "html-documentation", 19 | "package": "./package.json", 20 | "readme": "./README.md" 21 | } 22 | } -------------------------------------------------------------------------------- /doc/jscc_manual.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abrobston/jscc/3e3043a7519b00dc9aebfc8f5850cca9237b97ec/doc/jscc_manual.odt -------------------------------------------------------------------------------- /doc/jscc_manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abrobston/jscc/3e3043a7519b00dc9aebfc8f5850cca9237b97ec/doc/jscc_manual.pdf -------------------------------------------------------------------------------- /exports-require.js: -------------------------------------------------------------------------------- 1 | //noinspection ThisExpressionReferencesGlobalObjectJS 2 | /** @suppress {globalThis} */ 3 | (this["require"] = require); -------------------------------------------------------------------------------- /exports-requireLib.js: -------------------------------------------------------------------------------- 1 | //noinspection ThisExpressionReferencesGlobalObjectJS 2 | /** @suppress {globalThis} */ 3 | (this["requireLib"] = require); 4 | -------------------------------------------------------------------------------- /exports.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Export statements for Closure's use. 3 | */ 4 | jscc['enums'] = jscc.enums; 5 | //noinspection ThisExpressionReferencesGlobalObjectJS 6 | /** @suppress {globalThis} */ 7 | (this['jscc'] = jscc); 8 | //>>includeStart("amdclean", pragmas.amdclean); 9 | //noinspection ThisExpressionReferencesGlobalObjectJS 10 | /** @suppress {globalThis|checkVars} */ 11 | (function(root) { 12 | if (typeof main !== "undefined") { 13 | (root['main'] = main); 14 | } 15 | })(this); 16 | //>>includeEnd("amdclean"); 17 | -------------------------------------------------------------------------------- /fileoverview-node.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * @suppress {uselessCode|globalThis} 4 | */ -------------------------------------------------------------------------------- /fileoverview.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * @suppress {globalThis} 4 | */ -------------------------------------------------------------------------------- /global-backfills.js: -------------------------------------------------------------------------------- 1 | (function(context) { 2 | if (typeof context.setTimeout !== "function") { 3 | /** 4 | * @param {?(Function|string)} callback 5 | * @param {number=} interval 6 | * @param {...*} extras 7 | * @returns {number} 8 | */ 9 | context.setTimeout = function(callback, interval, extras) { 10 | // Ignore the interval, as we just want to ensure that the callback 11 | // itself is called. Also, accepting a string callback is just 12 | // to make Closure happy -- we don't currently need to handle it. 13 | if (typeof callback === "function") { 14 | callback(); 15 | } 16 | return 0; 17 | } 18 | } 19 | })(this); 20 | -------------------------------------------------------------------------------- /lib/jscc/bitset/BitSet32.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for a bitset implementation backed by 3 | * integer bitmasks. 4 | */ 5 | (function(root, factory) { 6 | /* istanbul ignore next */ 7 | if (typeof define === 'function' && define.amd) { 8 | define(factory); 9 | } else if (typeof module === 'object' && module.exports) { 10 | module.exports = factory(); 11 | } else { 12 | root.jsccbitset = factory(); 13 | } 14 | }(this, function() { 15 | //>>excludeStart("closure", pragmas.closure); 16 | var jscc = {}; 17 | //>>excludeEnd("closure"); 18 | /** 19 | * Creates a new BitSet32 object. 20 | * @classdesc A bitset implementation backed by integer bitmasks. 21 | * @implements {jscc.bitset} 22 | * @constructor 23 | */ 24 | jscc.BitSet32 = function() { 25 | var that = this; 26 | /** 27 | * @private 28 | * @type {!Array} 29 | */ 30 | this._data = []; 31 | /** 32 | * @inheritDoc 33 | * @param {!number} bit 34 | * @param {boolean=} state 35 | * @returns {!boolean} 36 | */ 37 | this.set = function(bit, state) { 38 | state = !!state; 39 | that._data[bit >> 5] = 40 | (state ? (that._data[bit >> 5] | (1 << (bit & 31))) : (that._data[bit >> 5] & ~(1 << (bit & 31)))); 41 | return state; 42 | }; 43 | /** 44 | * @inheritDoc 45 | * @param {!number} bit 46 | * @returns {!boolean} 47 | */ 48 | this.get = function(bit) { 49 | return ((that._data[bit >> 5] & (1 << (bit & 31))) != 0); 50 | }; 51 | /** 52 | * @inheritDoc 53 | * @returns {!number} 54 | */ 55 | this.count = function() { 56 | var i, l, c = 0; 57 | for (i = 0, l = that._data.length * 32; i < l; i++) { 58 | if (that.get(i)) { 59 | c++; 60 | } 61 | } 62 | return c; 63 | }; 64 | }; 65 | /** 66 | * Module containing BitSet32 implementation. Returns a factory 67 | * function to make Closure slightly happier elsewhere. 68 | * @module {function(new:jscc.BitSet32)} jscc/bitset/BitSet32 69 | */ 70 | return jscc.BitSet32; 71 | })); 72 | -------------------------------------------------------------------------------- /lib/jscc/bitset/BitSetBool.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for a boolean-backed bitset implementation. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(); 10 | } else { 11 | root.jsccbitset = factory(); 12 | } 13 | }(this, function() { 14 | //>>excludeStart("closure", pragmas.closure); 15 | var jscc = {}; 16 | //>>excludeEnd("closure"); 17 | /** 18 | * Boolean-backed bitset implementation. 19 | * @implements {jscc.bitset} 20 | * @constructor 21 | */ 22 | jscc.BitSetBool = function() { 23 | this._data = []; 24 | }; 25 | jscc.BitSetBool.prototype = { 26 | /** 27 | * @private 28 | * @type {!Array} 29 | */ 30 | _data: [], 31 | /** 32 | * @inheritDoc 33 | * @this {jscc.BitSetBool} 34 | */ 35 | set: function(bit, state) { 36 | return this._data[bit] = (state && true) || false; 37 | }, 38 | /** 39 | * @inheritDoc 40 | * @this {jscc.BitSetBool} 41 | */ 42 | get: function(bit) { 43 | return this._data[bit]; 44 | }, 45 | /** 46 | * @inheritDoc 47 | * @this {jscc.BitSetBool} 48 | */ 49 | count: function() { 50 | var i, c = 0; 51 | for (i = 0; i < this._data.length; i++) { 52 | if (this._data[i]) { 53 | c++; 54 | } 55 | } 56 | return c; 57 | } 58 | }; 59 | /** 60 | * @module {function(new:jscc.BitSetBool)} jscc/bitset/BitSetBool 61 | */ 62 | return jscc.BitSetBool; 63 | })); -------------------------------------------------------------------------------- /lib/jscc/bitset/BitSetJava.js: -------------------------------------------------------------------------------- 1 | (function(root, factory) { 2 | /* istanbul ignore next */ 3 | if (typeof define === 'function' && define.amd) { 4 | define(factory); 5 | } else if (typeof module === 'object' && module.exports) { 6 | module.exports = factory(); 7 | } else { 8 | root.jsccbitset = factory(); 9 | } 10 | }(this, function() { 11 | //>>excludeStart("closure", pragmas.closure); 12 | var jscc = {}; 13 | //>>excludeEnd("closure"); 14 | /** 15 | * @type {function(new:java.util.BitSet)} 16 | */ 17 | var JavaBitSet; 18 | //>>includeStart("nashorn", pragmas.nashorn); 19 | JavaBitSet = /** @type {function(new:java.util.BitSet)} */ (Java.type("java.util.BitSet")); 20 | //>>includeEnd("nashorn"); 21 | //>>excludeStart("nashorn", pragmas.nashorn); 22 | JavaBitSet = java.util.BitSet; 23 | //>>excludeEnd("nashorn"); 24 | /** 25 | * Java library bitset implementation. 26 | * @implements {jscc.bitset} 27 | * @constructor 28 | */ 29 | jscc.BitSetJava = function() { 30 | this._inner = new JavaBitSet(); 31 | }; 32 | 33 | /** 34 | * @type {java.util.BitSet} 35 | * @private 36 | */ 37 | jscc.BitSetJava.prototype._inner = null; 38 | /** 39 | * @inheritDoc 40 | * @this {jscc.BitSetJava} 41 | * @param {!number} bit 42 | * @param {boolean=} state 43 | * @returns {!boolean} 44 | */ 45 | jscc.BitSetJava.prototype.set = function(bit, state) { 46 | var flag = (state && true) || false; 47 | this._inner.set(bit, flag); 48 | return flag; 49 | }; 50 | 51 | /** 52 | * @inheritDoc 53 | * @this {jscc.BitSetJava} 54 | * @param {!number} bit 55 | * @returns {!boolean} 56 | */ 57 | jscc.BitSetJava.prototype.get = function(bit) { 58 | return this._inner.get(bit); 59 | }; 60 | 61 | /** 62 | * @inheritDoc 63 | * @this {jscc.BitSetJava} 64 | * @returns {!number} 65 | */ 66 | jscc.BitSetJava.prototype.count = function() { 67 | return this._inner.cardinality(); 68 | }; 69 | 70 | /** 71 | * @module {function(new:jscc.BitSetJava)} jscc/bitset/BitSetJava 72 | */ 73 | return jscc.BitSetJava; 74 | })); -------------------------------------------------------------------------------- /lib/jscc/bitset/bitset.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface definition for bitset implementations. 3 | * @interface 4 | */ 5 | jscc.bitset = function() { 6 | }; 7 | jscc.bitset.prototype = { 8 | /** 9 | * Sets the specified bit to true or false. 10 | * @param {!number} bit - The index of the bit to set 11 | * @param {boolean=} state - Whether to set the bit to true or false 12 | * @returns {!boolean} Returns the state parameter for chaining purposes 13 | * @method 14 | */ 15 | set: function(bit, state) { 16 | return false; 17 | }, 18 | 19 | /** 20 | * Gets the bit at the specified index. 21 | * @param {!number} bit - The index of the bit to get 22 | * @returns {!boolean} Whether the bit is currently true or false 23 | * @method 24 | */ 25 | get: function(bit) { 26 | return false; 27 | }, 28 | 29 | /** 30 | * Returns the number of true values in the bitset. 31 | * @returns {!number} The number of true values in the bitset 32 | * @method 33 | */ 34 | count: function() { 35 | return 0; 36 | } 37 | }; -------------------------------------------------------------------------------- /lib/jscc/classes/Dfa.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for module containing Dfa class. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(); 10 | } else { 11 | root.jsccDfa = factory(); 12 | } 13 | }(this, function() { 14 | //>>excludeStart("closure", pragmas.closure) 15 | var jscc = { 16 | classes: {} 17 | }; 18 | //>>excludeEnd("closure"); 19 | /** 20 | * Creates a new Dfa instance. 21 | * @classdesc Represents a state in a deterministic finite automata. 22 | * @param {DfaOptions=} o - Optional overrides for default property values. 23 | * @constructor 24 | */ 25 | jscc.classes.Dfa = function(o) { 26 | var p = o || {}; 27 | if (typeof p.line !== 'undefined' && Array.isArray(p.line)) { 28 | this.line = /** @type {!Array} */ (p.line); 29 | } 30 | if (typeof p.nfa_set !== 'undefined' && Array.isArray(p.nfa_set)) { 31 | this.nfa_set = /** @type {!Array} */ (p.nfa_set); 32 | } 33 | if (typeof p.accept === 'number') { 34 | this.accept = /** @type {!number} */ (p.accept); 35 | } 36 | if (typeof p.done === 'boolean') { 37 | this.done = /** @type {!boolean} */ (p.done); 38 | } 39 | if (typeof p.group === 'number') { 40 | this.group = /** @type {!number} */ (p.group); 41 | } 42 | }; 43 | 44 | /** 45 | * A multidimensional, generated array corresponding to this DFA state. 46 | * @type {!Array} 47 | */ 48 | jscc.classes.Dfa.prototype.line = []; 49 | /** 50 | * Indexes of NFA states represented in this DFA state. 51 | * @type {!Array} 52 | */ 53 | jscc.classes.Dfa.prototype.nfa_set = []; 54 | /** 55 | * Index of an accepting state. 56 | * @type {!number} 57 | */ 58 | jscc.classes.Dfa.prototype.accept = -1; 59 | /** 60 | * Whether this DFA state has been fully processed. 61 | * @type {!boolean} 62 | */ 63 | jscc.classes.Dfa.prototype.done = false; 64 | /** 65 | * A group index for this DFA state. 66 | * @type {!number} 67 | */ 68 | jscc.classes.Dfa.prototype.group = -1; 69 | 70 | /** 71 | * The module containing the Dfa class. 72 | * @module {function(new:jscc.classes.Dfa, DfaOptions=)} jscc/classes/Dfa 73 | */ 74 | return jscc.classes.Dfa; 75 | })); 76 | -------------------------------------------------------------------------------- /lib/jscc/classes/Item.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for module containing the Item class. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(); 10 | } else { 11 | root.jsccItem = factory(); 12 | } 13 | }(this, function() { 14 | //>>excludeStart("closure", pragmas.closure); 15 | var jscc = { 16 | classes: {} 17 | }; 18 | //>>excludeEnd("closure"); 19 | /** 20 | * Creates a new Item instance. 21 | * @classdesc Contains lookahead information associated with a production. 22 | * @param {ItemOptions=} o - Optional overrides for default property values. 23 | * @constructor 24 | * @const 25 | */ 26 | jscc.classes.Item = function(o) { 27 | var p = o || {}; 28 | if (typeof p.prod === 'number') { 29 | this.prod = /** @type {!number} */ (p.prod); 30 | } 31 | if (typeof p.dot_offset === 'number') { 32 | this.dot_offset = /** @type {!number} */ (p.dot_offset); 33 | } 34 | if (typeof p.lookahead !== 'undefined' && Array.isArray(p.lookahead)) { 35 | this.lookahead = /** @type {!Array} */ (p.lookahead); 36 | } 37 | }; 38 | 39 | /** 40 | * The index within the global productions array of the production associated with this item. 41 | * @type {!number} 42 | */ 43 | jscc.classes.Item.prototype.prod = -1; 44 | /** 45 | * The dot offset. 46 | * @type {!number} 47 | */ 48 | jscc.classes.Item.prototype.dot_offset = 0; 49 | /** 50 | * An array of lookahead indexes. 51 | * @type {!Array} 52 | */ 53 | jscc.classes.Item.prototype.lookahead = []; 54 | 55 | /** 56 | * The module containing the Item class. 57 | * @module {function(new:jscc.classes.Item, ItemOptions=)} jscc/classes/Item 58 | */ 59 | return jscc.classes.Item; 60 | })); 61 | -------------------------------------------------------------------------------- /lib/jscc/classes/Nfa.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for module containing the Nfa class. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(['require', '../enums/EDGE', '../bitset'], factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(require); 10 | } else { 11 | root.jsccNfa = factory(function(mod) { 12 | return root["jscc" + mod.split("/").pop()]; 13 | }); 14 | } 15 | }(this, 16 | /** 17 | * @param {reqParameter} require 18 | * @param {...*} others 19 | * @returns {function(new:jscc.classes.Nfa, NfaOptions=)} 20 | */ 21 | function(require, others) { 22 | //>>excludeStart("closure", pragmas.closure); 23 | var jscc = { 24 | classes: {} 25 | }; 26 | var has = /** @type {hasObject} */ (require("../localHas")); 27 | //>>excludeEnd("closure"); 28 | var BitSet, tmpBitSet, EDGE = require("../enums/EDGE"); 29 | 30 | /** 31 | * @suppress {uselessCode} 32 | */ 33 | (function() { 34 | if (has("node")) { 35 | tmpBitSet = require("../bitset/BitSet32"); 36 | } else { 37 | tmpBitSet = require("../bitset"); 38 | } 39 | })(); 40 | BitSet = /** @type {function(new:jscc.bitset)} */ (tmpBitSet); 41 | 42 | /** 43 | * Creates a new Nfa instance. 44 | * @classdesc Represents a state in a nondeterministic finite automata. 45 | * @param {NfaOptions=} o - Optional overrides for default property values. 46 | * @constructor 47 | * @const 48 | */ 49 | jscc.classes.Nfa = function(o) { 50 | var p = o || {}; 51 | if (p.edge === EDGE.CHAR || p.edge === EDGE.FREE) { 52 | this.edge = /** @type {!jscc.enums.EDGE} */ (p.edge); 53 | } 54 | if (typeof p.ccl === 'object' && p.ccl.hasOwnProperty("get") && p.ccl.hasOwnProperty("set") && 55 | p.ccl.hasOwnProperty("count")) { 56 | this.ccl = /** @type {!jscc.bitset} */ (p.ccl); 57 | } else { 58 | this.ccl = new BitSet(); 59 | } 60 | if (typeof p.follow === 'number') { 61 | this.follow = /** @type {!number} */ (p.follow); 62 | } 63 | if (typeof p.follow2 === 'number') { 64 | this.follow2 = /** @type {!number} */ (p.follow2); 65 | } 66 | if (typeof p.accept === 'number') { 67 | this.accept = /** @type {!number} */ (p.accept); 68 | } 69 | if (typeof p.weight === 'number') { 70 | this.weight = /** @type {!number} */ (p.weight); 71 | } 72 | }; 73 | 74 | /** 75 | * The type of edge in this NFA state. 76 | * @type {!jscc.enums.EDGE} 77 | */ 78 | jscc.classes.Nfa.prototype.edge = EDGE.EPSILON; 79 | /** 80 | * The bitset for this NFA state. 81 | * @type {!jscc.bitset} 82 | */ 83 | jscc.classes.Nfa.prototype.ccl = new BitSet(); 84 | /** 85 | * Index of an immediately-following state. 86 | * @type {!number} 87 | */ 88 | jscc.classes.Nfa.prototype.follow = -1; 89 | /** 90 | * Index of a second following state. 91 | * @type {!number} 92 | */ 93 | jscc.classes.Nfa.prototype.follow2 = -1; 94 | /** 95 | * Index of an accepting state. 96 | * @type {!number} 97 | */ 98 | jscc.classes.Nfa.prototype.accept = -1; 99 | /** 100 | * The weight of this particular state. 101 | * @type {!number} 102 | */ 103 | jscc.classes.Nfa.prototype.weight = -1; 104 | 105 | /** 106 | * The module containing the Nfa class. 107 | * @module jscc/classes/Nfa 108 | */ 109 | return jscc.classes.Nfa; 110 | })); 111 | -------------------------------------------------------------------------------- /lib/jscc/classes/Param.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for module containing Param class. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(); 10 | } else { 11 | root.jsccParam = factory(); 12 | } 13 | }(this, function() { 14 | //>>excludeStart("closure", pragmas.closure); 15 | var jscc = { 16 | classes: {} 17 | }; 18 | //>>excludeEnd("closure"); 19 | /** 20 | * Creates a new Param instance. 21 | * @classdesc Contains indexes of start and end states. 22 | * @param {number=} start - Index of the starting state. 23 | * @param {number=} end - Index of the ending state. 24 | * @constructor 25 | * @memberof {jscc.classes} 26 | * @const 27 | */ 28 | jscc.classes.Param = function(start, end) { 29 | if (typeof start === 'number') { 30 | this.start = start; 31 | } 32 | if (typeof end === 'number') { 33 | this.end = end; 34 | } 35 | }; 36 | 37 | /** 38 | * Index of the starting state. 39 | * @type {!number} 40 | */ 41 | jscc.classes.Param.prototype.start = -1; 42 | /** 43 | * Index of the ending state. 44 | * @type {!number} 45 | */ 46 | jscc.classes.Param.prototype.end = -1; 47 | 48 | /** 49 | * The module containing the Param class. 50 | * @module jscc/classes/Param 51 | */ 52 | return jscc.classes.Param; 53 | })); 54 | -------------------------------------------------------------------------------- /lib/jscc/classes/Production.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for Production class. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(); 10 | } else { 11 | root.jsccProduction = factory(); 12 | } 13 | }(this, function() { 14 | //>>excludeStart("closure", pragmas.closure); 15 | var jscc = { 16 | classes: {} 17 | }; 18 | //>>excludeEnd("closure"); 19 | /** 20 | * Creates a new Production instance. 21 | * @classdesc Represents a production created from the grammar. 22 | * @param {ProductionOptions=} o - Overrides for default property values. 23 | * @constructor 24 | * @memberof {jscc.classes} 25 | * @const 26 | */ 27 | jscc.classes.Production = function(o) { 28 | var p = o || {}; 29 | if (typeof p.id === 'number') { 30 | this.id = /** @type {number} */ (p.id); 31 | } 32 | if (typeof p.lhs === 'number') { 33 | this.lhs = /** @type {number} */ (p.lhs); 34 | } 35 | if (typeof p.rhs !== 'undefined' && Array.isArray(p.rhs)) { 36 | this.rhs = /** @type {!Array} */ (p.rhs); 37 | } 38 | if (typeof p.level === 'number') { 39 | this.level = /** @type {number} */ (p.level); 40 | } 41 | if (typeof p.code === 'string') { 42 | this.code = /** @type {string} */ (p.code); 43 | } 44 | }; 45 | 46 | /** 47 | * The unique identifier of this production, which should 48 | * match its index within the global productions array. 49 | * @type {!number} 50 | */ 51 | jscc.classes.Production.prototype.id = -1; 52 | /** 53 | * The id of the symbol representing the left-hand side of 54 | * this production. 55 | * @type {!number} 56 | */ 57 | jscc.classes.Production.prototype.lhs = -1; 58 | /** 59 | * The id values of the symbols representing the right-hand side 60 | * of this production. 61 | * @type {!Array} 62 | */ 63 | jscc.classes.Production.prototype.rhs = []; 64 | /** 65 | * The level of this production. 66 | * @type {!number} 67 | */ 68 | jscc.classes.Production.prototype.level = 0; 69 | /** 70 | * The code associated with this production. 71 | * @type {!string} 72 | */ 73 | jscc.classes.Production.prototype.code = ""; 74 | 75 | /** 76 | * Contains the Production class. 77 | * @module {function(new:jscc.classes.Production, ProductionOptions=)} jscc/classes/Production 78 | */ 79 | return jscc.classes.Production; 80 | })); 81 | -------------------------------------------------------------------------------- /lib/jscc/classes/State.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for module containing State class. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(); 10 | } else { 11 | root.jsccState = factory(); 12 | } 13 | }(this, function() { 14 | //>>excludeStart("closure", pragmas.closure); 15 | var jscc = { 16 | classes: {} 17 | }; 18 | //>>excludeEnd("closure"); 19 | /** 20 | * Creates a new State instance. 21 | * @classdesc Represents a state machine entry. 22 | * @param {StateOptions=} o - Optional overrides for default property values. 23 | * @constructor 24 | * @memberof {jscc.classes} 25 | */ 26 | jscc.classes.State = function(o) { 27 | var p = o || {}; 28 | if (Array.isArray(p.kernel)) { 29 | this.kernel = /** @type {!Array} */ (p.kernel); 30 | } 31 | if (Array.isArray(p.epsilon)) { 32 | this.epsilon = /** @type {!Array} */ (p.epsilon); 33 | } 34 | if (typeof p.def_act === 'number') { 35 | this.def_act = /** @type {!number} */ (p.def_act); 36 | } 37 | if (typeof p.done === 'boolean') { 38 | this.done = /** @type {!boolean} */ (p.done); 39 | } 40 | if (typeof p.closed === 'boolean') { 41 | this.closed = /** @type {!boolean} */ (p.closed); 42 | } 43 | if (Array.isArray(p.actionrow)) { 44 | this.actionrow = /** @type {!Array} */ (p.actionrow); 45 | } 46 | if (Array.isArray(p.gotorow)) { 47 | this.gotorow = /** @type {!Array} */ (p.gotorow); 48 | } 49 | }; 50 | 51 | /** 52 | * An array of items forming the kernel of this state. 53 | * @type {!Array} 54 | */ 55 | jscc.classes.State.prototype.kernel = []; 56 | /** 57 | * An array of items forming the epsilon of this state. 58 | * @type {!Array} 59 | */ 60 | jscc.classes.State.prototype.epsilon = []; 61 | /** 62 | * A number representing a defined action. 63 | * @type {!number} 64 | */ 65 | jscc.classes.State.prototype.def_act = 0; 66 | /** 67 | * Whether this state has been fully processed. 68 | * @type {!boolean} 69 | */ 70 | jscc.classes.State.prototype.done = false; 71 | /** 72 | * Whether this state is closed. 73 | * @type {!boolean} 74 | */ 75 | jscc.classes.State.prototype.closed = false; 76 | /** 77 | * Table entries representing actions for this state. 78 | * @type {!Array} 79 | */ 80 | jscc.classes.State.prototype.actionrow = []; 81 | /** 82 | * Table entries representing goto operations for this state. 83 | * @type {!Array} 84 | */ 85 | jscc.classes.State.prototype.gotorow = []; 86 | 87 | /** 88 | * The module containing the State class. 89 | * @module jscc/classes/State 90 | */ 91 | return jscc.classes.State; 92 | })); 93 | -------------------------------------------------------------------------------- /lib/jscc/classes/Symbol.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for the Symbol class module. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(["require", "../enums/SYM", "../enums/ASSOC", "../enums/SPECIAL"], factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(require); 10 | } else { 11 | root.jsccSymbol = factory(function(mod) { 12 | return root["jscc" + mod.split("/").pop()]; 13 | }); 14 | } 15 | }(this, 16 | /** 17 | * @param {reqParameter} require 18 | * @param {...*} others 19 | * @returns {function(new:jscc.classes.Symbol, SymbolOptions=)} 20 | */ 21 | function(require, others) { 22 | //>>excludeStart("closure", pragmas.closure); 23 | var jscc = { 24 | classes: {} 25 | }; 26 | //>>excludeEnd("closure"); 27 | 28 | var SYM = require("../enums/SYM"), 29 | ASSOC = require("../enums/ASSOC"), 30 | SPECIAL = require("../enums/SPECIAL"); 31 | 32 | /** 33 | * Creates a new Symbol instance. 34 | * @classdesc Represents a symbol in the grammar. 35 | * @param {SymbolOptions=} o - Optional overrides for default property values. 36 | * @constructor 37 | * @memberof {jscc.classes} 38 | * @const 39 | */ 40 | jscc.classes.Symbol = function(o) { 41 | var p = o || {}; 42 | if (typeof p.id === 'number') { 43 | this.id = p.id; 44 | } 45 | if (p.kind === SYM.TERM) { 46 | this.kind = p.kind; 47 | } 48 | if (typeof p.label === 'string') { 49 | this.label = p.label; 50 | } 51 | if (Array.isArray(p.prods)) { 52 | this.prods = /** @type {!Array} */ (p.prods); 53 | } 54 | if (Array.isArray(p.first)) { 55 | this.first = /** @type {!Array} */ (p.first); 56 | } 57 | if (p.associativity === ASSOC.LEFT || 58 | p.associativity === ASSOC.RIGHT || 59 | p.associativity === ASSOC.NOASSOC) { 60 | this.associativity = p.associativity; 61 | } 62 | if (typeof p.level === 'number') { 63 | this.level = p.level; 64 | } 65 | if (typeof p.code === 'string') { 66 | this.code = p.code; 67 | } 68 | if (p.special === SPECIAL.EOF || 69 | p.special === SPECIAL.ERROR || 70 | p.special === SPECIAL.WHITESPACE) { 71 | this.special = p.special; 72 | } 73 | if (typeof p.nullable === 'boolean') { 74 | this.nullable = p.nullable; 75 | } 76 | if (typeof p.defined === 'boolean') { 77 | this.defined = p.defined; 78 | } 79 | }; 80 | 81 | /** 82 | * The unique identifier for this symbol. Generally, this value should match the symbol's index within the 83 | * global symbol array. 84 | * @type {!number} 85 | */ 86 | jscc.classes.Symbol.prototype.id = -1; 87 | /** 88 | * Whether the symbol is terminating or nonterminating. 89 | * @type {!jscc.enums.SYM} 90 | */ 91 | jscc.classes.Symbol.prototype.kind = SYM.NONTERM; 92 | /** 93 | * The text of this symbol. 94 | * @type {!string} 95 | */ 96 | jscc.classes.Symbol.prototype.label = ""; 97 | /** 98 | * The set of productions associated with this symbol, as identified by 99 | * their id values within the global productions array. 100 | * @type {!Array} 101 | */ 102 | jscc.classes.Symbol.prototype.prods = []; 103 | /** 104 | * The "first" array. 105 | * @type {!Array} 106 | */ 107 | jscc.classes.Symbol.prototype.first = []; 108 | /** 109 | * The associativity of this symbol. 110 | * @type {!jscc.enums.ASSOC} 111 | */ 112 | jscc.classes.Symbol.prototype.associativity = ASSOC.NONE; 113 | /** 114 | * The level of this symbol. 115 | * @type {!number} 116 | */ 117 | jscc.classes.Symbol.prototype.level = 0; 118 | /** 119 | * The code that this symbol produces. 120 | * @type {!string} 121 | */ 122 | jscc.classes.Symbol.prototype.code = ""; 123 | /** 124 | * The type of special symbol, if any, that this symbol represents. 125 | * @type {!jscc.enums.SPECIAL} 126 | */ 127 | jscc.classes.Symbol.prototype.special = SPECIAL.NONE; 128 | /** 129 | * Whether this symbol is nullable. 130 | * @type {!boolean} 131 | */ 132 | jscc.classes.Symbol.prototype.nullable = false; 133 | /** 134 | * Whether this symbol is defined. 135 | * @type {!boolean} 136 | */ 137 | jscc.classes.Symbol.prototype.defined = false; 138 | 139 | /** 140 | * The module containing the Symbol class. 141 | * @module {function(new:jscc.classes.Symbol, SymbolOptions=)} jscc/classes/Symbol 142 | */ 143 | return jscc.classes.Symbol; 144 | })); 145 | -------------------------------------------------------------------------------- /lib/jscc/classes/TableEntry.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for TableEntry class. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(); 10 | } else { 11 | root.jsccTableEntry = factory(); 12 | } 13 | }(this, function() { 14 | //>>excludeStart("closure", pragmas.closure); 15 | var jscc = { 16 | classes: {} 17 | }; 18 | //>>excludeEnd("closure"); 19 | /** 20 | * Creates a new TableEntry instance. 21 | * @classdesc An object used in the {@link jscc.classes.State#actionrow} and {@link jscc.classes.State#gotorow} 22 | * arrays to indicate how symbols and actions are paired for that state. 23 | * @param {number} sym - A number representing a {@link jscc.classes.Symbol#id} value. 24 | * @param {number} act - A number representing the action associated with the symbol. 25 | * @constructor 26 | * @memberof {jscc.classes} 27 | * @const 28 | */ 29 | jscc.classes.TableEntry = function(sym, act) { 30 | this.symbol = sym; 31 | this.action = act; 32 | }; 33 | 34 | /** 35 | * The id value of the Symbol with which this entry is associated. 36 | * @type {!number} 37 | */ 38 | jscc.classes.TableEntry.prototype.symbol = -1; 39 | /** 40 | * A number representing the action associated with the symbol. 41 | * @type {!number} 42 | */ 43 | jscc.classes.TableEntry.prototype.action = -1; 44 | 45 | /** 46 | * The module containing the TableEntry class. 47 | * @module jscc/classes/TableEntry 48 | */ 49 | return jscc.classes.TableEntry; 50 | })); 51 | -------------------------------------------------------------------------------- /lib/jscc/enums/ASSOC.js: -------------------------------------------------------------------------------- 1 | (function(root, factory) { 2 | /* istanbul ignore next */ 3 | if (typeof define === 'function' && define.amd) { 4 | define(factory); 5 | } else if (typeof module === 'object' && module.exports) { 6 | module.exports = factory(); 7 | } else { 8 | root.jsccASSOC = factory(); 9 | } 10 | }(this, function() { 11 | //>>excludeStart("closure", pragmas.closure); 12 | var jscc = { 13 | enums: {} 14 | }; 15 | /** 16 | * Indicates the associativity of a symbol. 17 | * @enum {number} 18 | * @memberof jscc.enums 19 | */ 20 | jscc.enums.ASSOC = { 21 | /** 22 | * The associativity has not yet been set. 23 | */ 24 | NONE: 0, 25 | /** 26 | * The symbol is left-associative. 27 | */ 28 | LEFT: 1, 29 | /** 30 | * The symbol is right-associative. 31 | */ 32 | RIGHT: 2, 33 | /** 34 | * The symbol is non-associative. 35 | */ 36 | NOASSOC: 3 37 | }; 38 | //>>excludeEnd("closure"); 39 | /** 40 | * Module containing ASSOC enumeration. 41 | * @module jscc/enums/ASSOC 42 | */ 43 | return jscc.enums.ASSOC; 44 | })); -------------------------------------------------------------------------------- /lib/jscc/enums/EDGE.js: -------------------------------------------------------------------------------- 1 | (function(root, factory) { 2 | /* istanbul ignore next */ 3 | if (typeof define === 'function' && define.amd) { 4 | define(factory); 5 | } else if (typeof module === 'object' && module.exports) { 6 | module.exports = factory(); 7 | } else { 8 | root.jsccEDGE = factory(); 9 | } 10 | }(this, function() { 11 | //>>excludeStart("closure", pragmas.closure); 12 | var jscc = { 13 | enums: {} 14 | }; 15 | /** 16 | * Identifies the type of an edge in an automation graph. 17 | * @enum {number} 18 | * @memberof jscc.enums 19 | */ 20 | jscc.enums.EDGE = { 21 | FREE: 0, 22 | EPSILON: 1, 23 | CHAR: 2 24 | }; 25 | //>>excludeEnd("closure"); 26 | /** 27 | * Module containing EDGE enumeration. 28 | * @module jscc/enums/EDGE 29 | */ 30 | return jscc.enums.EDGE; 31 | })); -------------------------------------------------------------------------------- /lib/jscc/enums/EXEC.js: -------------------------------------------------------------------------------- 1 | (function(root, factory) { 2 | /* istanbul ignore next */ 3 | if (typeof define === 'function' && define.amd) { 4 | define(factory); 5 | } else if (typeof module === 'object' && module.exports) { 6 | module.exports = factory(); 7 | } else { 8 | root.jsccEXEC = factory(); 9 | } 10 | }(this, function() { 11 | //>>excludeStart("closure", pragmas.closure); 12 | var jscc = { 13 | enums: {} 14 | }; 15 | /** 16 | * Indicates whether the executable environment is a 17 | * console-based Javascript engine or a web environment. 18 | * @enum {number} 19 | * @memberof jscc.enums 20 | */ 21 | jscc.enums.EXEC = { 22 | /** 23 | * A console-based Javascript engine is in use. 24 | */ 25 | CONSOLE: 0, 26 | /** 27 | * A web-browser-based Javascript engine is in use. 28 | */ 29 | WEB: 1 30 | }; 31 | //>>excludeEnd("closure"); 32 | /** 33 | * Module containing EXEC enumeration. 34 | * @module jscc/enums/EXEC 35 | */ 36 | return jscc.enums.EXEC; 37 | })); -------------------------------------------------------------------------------- /lib/jscc/enums/LOG_LEVEL.js: -------------------------------------------------------------------------------- 1 | (function(root, factory) { 2 | /* istanbul ignore next */ 3 | if (typeof define === 'function' && define.amd) { 4 | define(factory); 5 | } else if (typeof module === 'object' && module.exports) { 6 | module.exports = factory(); 7 | } else { 8 | root.jsccLOG_LEVEL = factory(); 9 | } 10 | }(this, function() { 11 | //>>excludeStart("closure", pragmas.closure); 12 | var jscc = { 13 | enums: {} 14 | }; 15 | /** 16 | * Specifies the minimum logging level. 17 | * @enum {number} 18 | * @memberof jscc.enums 19 | */ 20 | jscc.enums.LOG_LEVEL = { 21 | /** 22 | * Log all messages. 23 | */ 24 | TRACE: 0, 25 | /** 26 | * Log debug messages and higher. 27 | */ 28 | DEBUG: 1, 29 | /** 30 | * Log info messages and higher. 31 | */ 32 | INFO: 2, 33 | /** 34 | * Log warning messages and higher. 35 | */ 36 | WARN: 3, 37 | /** 38 | * Log error and fatal messages. 39 | */ 40 | ERROR: 4, 41 | /** 42 | * Log only fatal messages. 43 | */ 44 | FATAL: 5 45 | }; 46 | // Export from Closure, as this enumeration may be used in the 47 | // mainOptions typedef. 48 | jscc.enums.LOG_LEVEL['TRACE'] = jscc.enums.LOG_LEVEL.TRACE; 49 | jscc.enums.LOG_LEVEL['DEBUG'] = jscc.enums.LOG_LEVEL.DEBUG; 50 | jscc.enums.LOG_LEVEL['INFO'] = jscc.enums.LOG_LEVEL.INFO; 51 | jscc.enums.LOG_LEVEL['WARN'] = jscc.enums.LOG_LEVEL.WARN; 52 | jscc.enums.LOG_LEVEL['ERROR'] = jscc.enums.LOG_LEVEL.ERROR; 53 | jscc.enums.LOG_LEVEL['FATAL'] = jscc.enums.LOG_LEVEL.FATAL; 54 | jscc.enums['LOG_LEVEL'] = jscc.enums.LOG_LEVEL; 55 | //>>excludeEnd("closure"); 56 | /** 57 | * Module containing LOG_LEVEL enumeration. 58 | * @module jscc/enums/LOG_LEVEL 59 | */ 60 | return jscc.enums.LOG_LEVEL; 61 | })); -------------------------------------------------------------------------------- /lib/jscc/enums/MODE_GEN.js: -------------------------------------------------------------------------------- 1 | (function(root, factory) { 2 | /* istanbul ignore next */ 3 | if (typeof define === 'function' && define.amd) { 4 | define(factory); 5 | } else if (typeof module === 'object' && module.exports) { 6 | module.exports = factory(); 7 | } else { 8 | root.jsccMODE_GEN = factory(); 9 | } 10 | }(this, function() { 11 | //>>excludeStart("closure", pragmas.closure); 12 | var jscc = { 13 | enums: {} 14 | }; 15 | /** 16 | * Indicates an output mode for the parser. 17 | * @readonly 18 | * @enum {number} 19 | * @memberof jscc.enums 20 | */ 21 | jscc.enums.MODE_GEN = { 22 | /** 23 | * Output is plain text. 24 | */ 25 | TEXT: 0, 26 | /** 27 | * Output is JavaScript code. 28 | */ 29 | JS: 1, 30 | /** 31 | * Output is HTML-formatted. 32 | */ 33 | HTML: 2 34 | }; 35 | //>>excludeEnd("closure"); 36 | /** 37 | * Module containing MODE_GEN enumeration. 38 | * @module jscc/enums/MODE_GEN 39 | */ 40 | return jscc.enums.MODE_GEN; 41 | })); -------------------------------------------------------------------------------- /lib/jscc/enums/SPECIAL.js: -------------------------------------------------------------------------------- 1 | (function(root, factory) { 2 | /* istanbul ignore next */ 3 | if (typeof define === 'function' && define.amd) { 4 | define(factory); 5 | } else if (typeof module === 'object' && module.exports) { 6 | module.exports = factory(); 7 | } else { 8 | root.jsccSPECIAL = factory(); 9 | } 10 | }(this, function() { 11 | //>>excludeStart("closure", pragmas.closure); 12 | var jscc = { 13 | enums: {} 14 | }; 15 | /** 16 | * Identifies a special symbol. Special symbols include 17 | * end-of-file, whitespace, and error symbols. Use 18 | * NONE to indicate a non-special symbol. 19 | * @enum {number} 20 | * @memberof jscc.enums 21 | */ 22 | jscc.enums.SPECIAL = { 23 | /** 24 | * Identifies a non-special symbol. 25 | */ 26 | NONE: 0, 27 | /** 28 | * Identifies an end-of-file symbol. 29 | */ 30 | EOF: 1, 31 | /** 32 | * Identifies a whitespace symbol. 33 | */ 34 | WHITESPACE: 2, 35 | /** 36 | * Identifies an error symbol. 37 | */ 38 | ERROR: 3 39 | }; 40 | //>>excludeEnd("closure"); 41 | /** 42 | * Module containing SPECIAL enumeration. 43 | * @module jscc/enums/SPECIAL 44 | */ 45 | return jscc.enums.SPECIAL; 46 | })); -------------------------------------------------------------------------------- /lib/jscc/enums/SYM.js: -------------------------------------------------------------------------------- 1 | (function(root, factory) { 2 | /* istanbul ignore next */ 3 | if (typeof define === 'function' && define.amd) { 4 | define(factory); 5 | } else if (typeof module === 'object' && module.exports) { 6 | module.exports = factory(); 7 | } else { 8 | root.jsccSYM = factory(); 9 | } 10 | }(this, function() { 11 | //>>excludeStart("closure", pragmas.closure); 12 | var jscc = { 13 | enums: {} 14 | }; 15 | /** 16 | * Identifies a symbol as nonterminating or terminating. 17 | * @enum {number} 18 | * @memberof jscc.enums 19 | */ 20 | jscc.enums.SYM = { 21 | /** 22 | * The symbol is nonterminating. 23 | */ 24 | NONTERM: 0, 25 | /** 26 | * The symbol is terminating. 27 | */ 28 | TERM: 1 29 | }; 30 | //>>excludeEnd("closure"); 31 | /** 32 | * Module containing SYM enumeration. 33 | * @module jscc/enums/SYM 34 | */ 35 | return jscc.enums.SYM; 36 | })); -------------------------------------------------------------------------------- /lib/jscc/first.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for first. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(['require', './global', './util', './enums/SYM'], factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(require); 10 | } else { 11 | root.jsccfirst = factory(function(mod) { 12 | return root["jscc" + mod.split("/").pop()]; 13 | }); 14 | } 15 | }(this, 16 | /** 17 | * @param {reqParameter} require 18 | * @param {...*} others 19 | * @returns {jscc.first} 20 | */ 21 | function(require, others) { 22 | //>>excludeStart("closure", pragmas.closure); 23 | var jscc = {}; 24 | //>>excludeEnd("closure"); 25 | var global = /** @type {jscc.global} */ (require("./global")), 26 | util = /** @type {jscc.util} */ (require("./util")), 27 | SYM = require("./enums/SYM"); 28 | 29 | /** 30 | * Creates an instance of jscc.first. 31 | * @classdesc Functions relating to FIRST-sets. 32 | * @constructor 33 | */ 34 | jscc.first = function() { 35 | }; 36 | /** 37 | * Computes the FIRST-sets for all non-terminals of the grammar. 38 | * Must be called right after the parse and before the table 39 | * generation methods are performed. 40 | * @author Jan Max Meyer 41 | */ 42 | jscc.first.prototype.first = function() { 43 | var cnt = 0, 44 | old_cnt = 0; 45 | var nullable; 46 | 47 | do { 48 | old_cnt = cnt; 49 | cnt = 0; 50 | 51 | for (var i = 0; i < global.symbols.length; i++) { 52 | if (global.symbols[i].kind == SYM.NONTERM) { 53 | for (var j = 0; j < global.symbols[i].prods.length; j++) { 54 | nullable = false; 55 | for (var k = 0; k < global.productions[global.symbols[i].prods[j]].rhs.length; k++) { 56 | global.symbols[i].first = util.union(global.symbols[i].first, 57 | global.symbols[global.productions[global.symbols[i].prods[j]].rhs[k]].first); 58 | 59 | nullable = 60 | global.symbols[global.productions[global.symbols[i].prods[j]].rhs[k]].nullable; 61 | if (!nullable) { 62 | break; 63 | } 64 | } 65 | cnt += global.symbols[i].first.length; 66 | 67 | if (k == global.productions[global.symbols[i].prods[j]].rhs.length) { 68 | nullable = true; 69 | } 70 | 71 | if (nullable) { 72 | global.symbols[i].nullable = true; 73 | } 74 | } 75 | } 76 | } 77 | } while (cnt != old_cnt); 78 | }; 79 | 80 | /** 81 | * Returns all terminals that are possible from a given position 82 | * of a production's right-hand side. 83 | * @param {jscc.classes.Item} item - Item to which the lookaheads are added. 84 | * @param {jscc.classes.Production} p - The production where the computation 85 | * should be done. 86 | * @param {number} begin - The offset of the symbol where the 87 | * rhs_first() begins its calculations. 88 | * @returns {boolean} True if the whole rest of the right-hand side 89 | * can be null (epsilon), else false. 90 | * @author Jan Max Meyer 91 | */ 92 | jscc.first.prototype.rhs_first = function(item, p, begin) { 93 | var i; 94 | for (i = begin; i < p.rhs.length; i++) { 95 | item.lookahead = util.union(item.lookahead, global.symbols[p.rhs[i]].first); 96 | 97 | if (!global.symbols[p.rhs[i]].nullable) { 98 | return false; 99 | } 100 | } 101 | return true; 102 | }; 103 | /** 104 | * Functions relating to FIRST-sets. 105 | * @module {jscc.first} jscc/first 106 | * @requires module:jscc/global 107 | * @requires module:jscc/util 108 | */ 109 | return new jscc.first(); 110 | })); 111 | -------------------------------------------------------------------------------- /lib/jscc/integrity.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for integrity. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(['require', './global', './log/log', './enums/SYM'], factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(require); 10 | } else { 11 | root.jsccintegrity = factory(function(mod) { 12 | return root["jscc" + mod.split("/").pop()]; 13 | }); 14 | } 15 | }(this, 16 | /** 17 | * @param {reqParameter} require 18 | * @param {...*} others 19 | * @returns {jscc.integrity} 20 | */ 21 | function(require, others) { 22 | //>>excludeStart("closure", pragmas.closure); 23 | var jscc = {}; 24 | var has = /** @type {hasObject} */ (require("./localHas")); 25 | //>>excludeEnd("closure"); 26 | var log, global = /** @type {jscc.global} */ (require("./global")), 27 | SYM = require("./enums/SYM"); 28 | 29 | /** 30 | * @suppress {uselessCode} 31 | */ 32 | (function() { 33 | if (has("node")) { 34 | log = /** @type {jscc.log} */ (require("./log/logNode")); 35 | } else { 36 | log = /** @type {jscc.log} */ (require("./log/log")); 37 | } 38 | })(); 39 | 40 | /** 41 | * Error-checking functions. 42 | * @module {jscc.integrity} jscc/integrity 43 | * @requires module:jscc/global 44 | * @requires module:jscc/log/log 45 | */ 46 | 47 | /** 48 | * @constructor 49 | */ 50 | jscc.integrity = function() { 51 | }; 52 | 53 | jscc.integrity.prototype = { 54 | /** 55 | * Checks the {@link jscc.global.symbols} array for 56 | * nonterminating, undefined symbols. Logs an error if 57 | * any such symbols are found. 58 | */ 59 | undef: function() { 60 | for (var i = 0; i < global.symbols.length; i++) { 61 | if (global.symbols[i].kind == SYM.NONTERM 62 | && global.symbols[i].defined == false) { 63 | log.error("Call to undefined non-terminal \"" + 64 | global.symbols[i].label + "\""); 65 | } 66 | } 67 | }, 68 | 69 | /** 70 | * Checks the {@link jscc.global.symbols} and 71 | * {@link jscc.global.productions} arrays for 72 | * unreachable, nonterminating symbols. Logs a warning 73 | * if any such symbols are found. 74 | */ 75 | unreachable: function() { 76 | var stack = []; 77 | var reachable = []; 78 | var i, j, k, l; 79 | 80 | for (i = 0; i < global.symbols.length; i++) { 81 | if (global.symbols[i].kind == SYM.NONTERM) { 82 | break; 83 | } 84 | } 85 | 86 | if (i == global.symbols.length) { 87 | return; 88 | } 89 | 90 | stack.push(i); 91 | reachable.push(i); 92 | 93 | while (stack.length > 0) { 94 | i = stack.pop(); 95 | for (j = 0; j < global.symbols[i].prods.length; j++) { 96 | for (k = 0; k < global.productions[global.symbols[i].prods[j]].rhs.length; k++) { 97 | if (global.symbols[global.productions[global.symbols[i].prods[j]].rhs[k]].kind == 98 | SYM.NONTERM) { 99 | for (l = 0; l < reachable.length; l++) { 100 | if (reachable[l] == global.productions[global.symbols[i].prods[j]].rhs[k]) { 101 | break; 102 | } 103 | } 104 | 105 | if (l == reachable.length) { 106 | stack.push(global.productions[global.symbols[i].prods[j]].rhs[k]); 107 | reachable.push(global.productions[global.symbols[i].prods[j]].rhs[k]); 108 | } 109 | } 110 | } 111 | } 112 | } 113 | 114 | for (i = 0; i < global.symbols.length; i++) { 115 | if (global.symbols[i].kind == SYM.NONTERM) { 116 | for (j = 0; j < reachable.length; j++) { 117 | if (reachable[j] == i) { 118 | break; 119 | } 120 | } 121 | if (j == reachable.length) { 122 | log.warn("Unreachable non-terminal \"" + global.symbols[i].label + "\""); 123 | } 124 | } 125 | } 126 | }, 127 | 128 | /** 129 | * Checks the {@link jscc.global.states} array for 130 | * states with no lookahead information. Logs an error 131 | * if any such states are found. 132 | */ 133 | check_empty_states: function() { 134 | for (var i = 0; i < global.states.length; i++) { 135 | if (global.states[i].actionrow.length == 0 && global.states[i].def_act == -1) { 136 | log.error("No lookaheads in state " + i + ", watch for endless list definitions"); 137 | } 138 | } 139 | } 140 | }; 141 | return new jscc.integrity(); 142 | })); 143 | -------------------------------------------------------------------------------- /lib/jscc/io/io.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @typedef {{filename: ?(string|undefined), chunkCallback: ?(function(string):void|undefined), endCallback: 3 | * ?(function():void|undefined)}} 4 | * @property {?(string|undefined)} filename - The filename to read. If omitted, read from standard input. 5 | * @property {?(function(string):void|undefined)} chunkCallback - The function to call when an input chunk is read 6 | * asynchronously. 7 | * @property {?(function():void|undefined)} endCallback - The function to call when the asynchronous read operation has 8 | * completed. 9 | */ 10 | var ioOptions; 11 | /** 12 | * @typedef {{text: string, destination: ?(string|undefined), callback: ?(function():void|undefined)}} 13 | * @property {string} text - The text to be written. 14 | * @property {?(string|undefined)} destination - The filename to which to write the text. If omitted, text is written 15 | * to standard output. 16 | * @property {?(function():void|undefined)} callback - A callback to be executed when the asynchronous write operation 17 | * has completed. If omitted, the operation occurs synchronously instead. 18 | */ 19 | var ioWriteOutputOptions; 20 | /** 21 | * Interface for engine-specific IO modules. 22 | * @interface 23 | */ 24 | jscc.io = function() { 25 | }; 26 | jscc.io.prototype = { 27 | /** 28 | * Reads input from the specified file or from standard input. 29 | * If chunkCallback and/or endCallback are specified, the operation 30 | * is asynchronous, and the function returns nothing. Otherwise, 31 | * the operation is synchronous, and the function returns a string 32 | * with the contents read from the file or from standard input. 33 | * 34 | * @param {(string|function(string):void|ioOptions)=} options - 35 | * If a string, the filename to read. If an object, has optional filename, chunkCallback, and endCallback 36 | * properties. If a function, the callback function to execute for each chunk read from standard input. 37 | * @returns {(string|void)} When running synchronously, the text read from 38 | * the file or standard input. When running asynchronously, returns nothing. 39 | */ 40 | read_all_input: function(options) { 41 | 42 | }, 43 | 44 | /** 45 | * Reads the template file into which the parser code is inserted. 46 | * If not specified, uses the default driver specified in 47 | * {@link jscc.global.DEFAULT_DRIVER}. 48 | * 49 | * @param {(string|function(string):void|ioOptions)=} options - 50 | * If a string, specifies the template filename. If a function, specifies the callback function to be used 51 | * when reading a file chunk has completed. If an object, specifies either or both. If omitted, causes the 52 | * function to read 53 | * {@link jscc.global.DEFAULT_DRIVER} synchronously. 54 | * @returns {(string|void)} When running synchronously, returns the contents of 55 | * the template file as a string. When running asynchronously, returns 56 | * nothing. 57 | */ 58 | read_template: function(options) { 59 | 60 | }, 61 | 62 | /** 63 | * Writes the provided text to the specified file or to standard output. 64 | * 65 | * @param {(string|ioWriteOutputOptions)} options - When a string, the text 66 | * to be written to standard output. When an object, contains text, destination, and callback properties. 67 | */ 68 | write_output: function(options) { 69 | 70 | }, 71 | 72 | /** 73 | * Writes the provided text to a debugging output, provided that such an output 74 | * exists in the implementation of this interface. 75 | * 76 | * @param {string} text - The text to write to the debugging output. 77 | */ 78 | write_debug: function(text) { 79 | 80 | }, 81 | 82 | /** 83 | * Attempts to exit the entire process with the provided exit code if the 84 | * platform supports doing so. Callers should also ensure that all functions 85 | * exit appropriately if the platform does not support this feature. 86 | * 87 | * @param {number=} exitCode - The exit code to use. 88 | */ 89 | exit: function(exitCode) { 90 | 91 | } 92 | }; 93 | -------------------------------------------------------------------------------- /lib/jscc/io/ioBrowser.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for browser-specific IO. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(['require', '../global'], factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(require); 10 | } else { 11 | root.jsccio = factory(function(mod) { 12 | return root["jscc" + mod.split("/").pop()]; 13 | }); 14 | } 15 | }(this, function(/** reqParameter */ require) { 16 | //>>excludeStart("closure", pragmas.closure); 17 | var jscc = {}; 18 | //>>excludeEnd("closure"); 19 | var global = /** @type {jscc.global} */ (require("../global")); 20 | 21 | /** 22 | * @constructor 23 | * @implements {jscc.io} 24 | */ 25 | jscc.ioBrowser = function() { 26 | }; 27 | 28 | /** 29 | * @inheritDoc 30 | */ 31 | jscc.ioBrowser.prototype.read_all_input = function(options) { 32 | if (typeof global.read_all_input_function === 'function') { 33 | options = options || {}; 34 | if (typeof options.chunkCallback === 'function') { 35 | var chunkCallback = options.chunkCallback; 36 | var endCallback = (typeof options.endCallback === 'function') ? options.endCallback : function() { 37 | }; 38 | chunkCallback(global.read_all_input_function()); 39 | endCallback(); 40 | } else { 41 | return global.read_all_input_function(); 42 | } 43 | } else { 44 | throw new Error("global.read_all_input_function was not defined"); 45 | } 46 | }; 47 | 48 | /** 49 | * @inheritDoc 50 | */ 51 | jscc.ioBrowser.prototype.read_template = function(options) { 52 | if (typeof global.read_template_function === 'function') { 53 | options = options || {}; 54 | if (typeof options.chunkCallback === 'function') { 55 | var chunkCallback = options.chunkCallback; 56 | var endCallback = (typeof options.endCallback === 'function') ? options.endCallback : function() { 57 | }; 58 | chunkCallback(global.read_template_function()); 59 | endCallback(); 60 | } else { 61 | return global.read_template_function(); 62 | } 63 | } else { 64 | throw new Error("global.read_template_function was not defined"); 65 | } 66 | }; 67 | 68 | /** 69 | * @inheritDoc 70 | */ 71 | jscc.ioBrowser.prototype.write_output = function(options) { 72 | if (typeof global.write_output_function === 'function') { 73 | var text = ""; 74 | var callback = function() { 75 | }; 76 | if (typeof options === 'string') { 77 | text = options; 78 | } else if (options && (typeof options === 'object')) { 79 | if (typeof options.text === 'string') { 80 | text = options.text; 81 | } else { 82 | throw new Error("options was not a string, and options.text was not a string"); 83 | } 84 | if (typeof options.callback === 'function') { 85 | callback = options.callback; 86 | } 87 | } 88 | global.write_output_function(text); 89 | callback(); 90 | } else { 91 | throw new Error("global.write_output_function was not defined"); 92 | } 93 | }; 94 | 95 | /** 96 | * @inheritDoc 97 | */ 98 | jscc.ioBrowser.prototype.write_debug = function(text) { 99 | if (typeof global.write_debug_function === 'function') { 100 | global.write_debug_function(text); 101 | } 102 | }; 103 | 104 | /** 105 | * @inheritDoc 106 | */ 107 | jscc.ioBrowser.prototype.exit = function(exitCode) { 108 | // Unsupported on most browser platforms. Although PhantomJS does support 109 | // this feature, for consistency, don't try. 110 | }; 111 | 112 | /** 113 | * @module jscc/io/io 114 | */ 115 | return new jscc.ioBrowser(); 116 | })); 117 | -------------------------------------------------------------------------------- /lib/jscc/io/ioNode.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for the Node version of the io module. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(['require', '../global'], factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(require); 10 | } else { 11 | root.jsccio = factory(function(mod) { 12 | return root["jscc" + mod.split("/").pop()]; 13 | }); 14 | } 15 | }(this, 16 | /** 17 | * @param {reqParameter} require 18 | * @param {...*} others 19 | * @returns {jscc.io} 20 | */ 21 | function(require, others) { 22 | //>>excludeStart("closure", pragmas.closure); 23 | var jscc = {}; 24 | //>>excludeEnd("closure"); 25 | var global = require("../global"), thisUtil, thisFs, thisPath; 26 | 27 | //>>excludeStart("amdclean", pragmas.amdclean); 28 | /* 29 | //>>excludeEnd("amdclean"); 30 | thisUtil = util; 31 | thisFs = fs; 32 | thisPath = path; 33 | //>>excludeStart("amdclean", pragmas.amdclean); 34 | */ 35 | thisUtil = require('util'); 36 | thisFs = require('fs'); 37 | thisPath = require('path'); 38 | //>>excludeEnd("amdclean"); 39 | 40 | /** 41 | * @constructor 42 | * @implements {jscc.io} 43 | */ 44 | jscc.ioNode = function() { 45 | }; 46 | 47 | /** 48 | * @inheritDoc 49 | */ 50 | jscc.ioNode.prototype.read_all_input = function(options) { 51 | var filename = ""; 52 | var async = false; 53 | /** 54 | * @param {string} chunk 55 | * @param {string=} encoding 56 | * @param {Function=} next 57 | */ 58 | var chunkCallback = function(chunk, encoding, next) { 59 | }; 60 | var endCallback = function() { 61 | }; 62 | if (options) { 63 | if (typeof options === "string") { 64 | filename = options; 65 | } else if (typeof options === "function") { 66 | // amdclean 67 | chunkCallback = /** @type {function(string)} */ (options); 68 | async = true; 69 | } else if (typeof options === "object") { 70 | if (typeof options.filename === "string") { 71 | filename = options.filename; 72 | } 73 | if (typeof options.chunkCallback === "function") { 74 | chunkCallback = options.chunkCallback; 75 | async = true; 76 | } 77 | if (typeof options.endCallback === "function") { 78 | endCallback = options.endCallback; 79 | async = true; 80 | } 81 | } 82 | } 83 | 84 | if (filename !== "" && !thisPath.isAbsolute(filename)) { 85 | filename = thisPath.join(process.cwd(), filename); 86 | } 87 | 88 | if (filename !== "" && !async) { 89 | return thisFs.readFileSync(filename, "utf-8"); 90 | } 91 | 92 | if (filename === "" && !async) { 93 | /** 94 | * @type {string} 95 | */ 96 | var result = ""; 97 | var done = false; 98 | process.stdin.setEncoding("utf-8"); 99 | process.stdin.on('end', function() { 100 | done = true; 101 | }); 102 | process.stdin.on('data', function(chunk, encoding, next) { 103 | result += "" + chunk; 104 | next(); 105 | }); 106 | while (!done) { 107 | 108 | } 109 | return /** @type {string} */ (result); 110 | } 111 | 112 | if (filename !== "") { 113 | thisFs.readFile(filename, "utf-8", chunkCallback); 114 | } else { 115 | process.stdin.setEncoding("utf-8"); 116 | process.stdin.on("end", endCallback); 117 | process.stdin.on("data", chunkCallback); 118 | } 119 | }; 120 | 121 | /** 122 | * @inheritDoc 123 | */ 124 | jscc.ioNode.prototype.read_template = function(options) { 125 | var filename = null; 126 | var async = false; 127 | 128 | /** 129 | * @param {string} chunk 130 | * @param {string=} encoding 131 | * @param {Function=} next 132 | */ 133 | var chunkCallback = function(chunk, encoding, next) { 134 | }; 135 | 136 | if (options) { 137 | if (typeof options === "string") { 138 | filename = options; 139 | } else if (typeof options === "function") { 140 | chunkCallback = options.chunkCallback; 141 | async = true; 142 | } else if (typeof options === "object") { 143 | if (typeof options.filename === "string") { 144 | filename = options.filename; 145 | } 146 | if (typeof options.chunkCallback === "function") { 147 | chunkCallback = options.chunkCallback; 148 | async = true; 149 | } 150 | } 151 | } 152 | 153 | if (filename === null) { 154 | if (async) { 155 | chunkCallback(global.DEFAULT_DRIVER, "utf-8", function() { 156 | }); 157 | } else { 158 | return global.DEFAULT_DRIVER; 159 | } 160 | } else { 161 | if (!thisPath.isAbsolute(filename)) { 162 | filename = thisPath.join(process.cwd(), filename); 163 | } 164 | if (!async) { 165 | return thisFs.readFileSync(filename, "utf-8"); 166 | } 167 | thisFs.readFile(filename, "utf-8", chunkCallback); 168 | } 169 | }; 170 | 171 | /** 172 | * @inheritDoc 173 | */ 174 | jscc.ioNode.prototype.write_output = function(options) { 175 | var text = ""; 176 | var destination = ""; 177 | var async = false; 178 | var callback = function() { 179 | }; 180 | 181 | if (options) { 182 | if (typeof options === "string") { 183 | text = options; 184 | } else if (typeof options === "object") { 185 | if (typeof options.text === "string") { 186 | text = options.text; 187 | } 188 | if (typeof options.destination === "string") { 189 | destination = options.destination; 190 | } 191 | if (typeof options.callback === "function") { 192 | callback = options.callback; 193 | async = true; 194 | } 195 | } 196 | } 197 | 198 | if (destination !== "" && !async) { 199 | thisFs.writeFileSync(destination, text, "utf-8"); 200 | } else if (destination === "" && !async) { 201 | process.stdout.write(text, "utf-8"); 202 | } else if (destination !== "") { 203 | thisFs.writeFile(destination, text, "utf-8", callback); 204 | } else { 205 | process.stdout.on('finish', callback); 206 | process.stdout.write(text, "utf-8"); 207 | process.stdout.end(); 208 | } 209 | }; 210 | 211 | /** 212 | * @inheritDoc 213 | */ 214 | jscc.ioNode.prototype.write_debug = function(text) { 215 | thisUtil.puts(text); 216 | }; 217 | 218 | /** 219 | * @inheritDoc 220 | */ 221 | jscc.ioNode.prototype.exit = function(exitCode) { 222 | process.exit(exitCode); 223 | }; 224 | 225 | /** 226 | * @module jscc/io/io 227 | */ 228 | return new jscc.ioNode(); 229 | })); 230 | 231 | -------------------------------------------------------------------------------- /lib/jscc/io/ioRhino.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for the Rhino version of the io module. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(['require', '../global', '../log/log'], factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(require); 10 | } else { 11 | root.jsccio = factory(function(mod) { 12 | return root["jscc" + mod.split("/").pop()]; 13 | }); 14 | } 15 | }(this, function(/** reqParameter */ require) { 16 | //>>excludeStart("closure", pragmas.closure); 17 | var jscc = {}; 18 | //>>excludeEnd("closure"); 19 | var global = /** @type {jscc.global} */ (require("../global")), 20 | log = /** @type {jscc.log} */ (require("../log/log")); 21 | 22 | /** 23 | * The Rhino version of the io module. 24 | * @implements {jscc.io} 25 | * @constructor 26 | */ 27 | jscc.ioRhino = function() { 28 | }; 29 | 30 | /** 31 | * @private 32 | * @param {string} file 33 | * @returns {string} 34 | */ 35 | jscc.ioRhino.prototype.read_file = function(file) { 36 | var src = ""; 37 | 38 | if ((new java.io.File(file)).exists()) { 39 | src = readFile(file); 40 | } else { 41 | log.error("unable to open file '" + file + "'"); 42 | quit(1); 43 | } 44 | 45 | return src; 46 | }; 47 | 48 | /** 49 | * @private 50 | * @param {string} file 51 | * @param {string} content 52 | * @returns {boolean} 53 | */ 54 | jscc.ioRhino.prototype.write_file = function(file, content) { 55 | var f = new java.io.PrintWriter(file); 56 | 57 | if (f) { 58 | f.write(content); 59 | f.close(); 60 | } else { 61 | log.error("unable to write '" + file + "'"); 62 | return false; 63 | } 64 | 65 | return true; 66 | }; 67 | 68 | /** 69 | * @inheritDoc 70 | */ 71 | jscc.ioRhino.prototype.read_all_input = function(options) { 72 | if (typeof options === 'string') { 73 | return this.read_file(options); 74 | } 75 | if (typeof options === 'object' && typeof options.filename === 'string') { 76 | if (typeof options.chunkCallback === 'function') { 77 | options.chunkCallback(this.read_file(options.filename)); 78 | if (typeof options.endCallback === 'function') { 79 | options.endCallback(); 80 | } 81 | } else { 82 | return this.read_file(options.filename); 83 | } 84 | } 85 | }; 86 | 87 | /** 88 | * @inheritDoc 89 | */ 90 | jscc.ioRhino.prototype.read_template = function(options) { 91 | var filename = global.DEFAULT_DRIVER; 92 | if (typeof options === 'string') { 93 | filename = options; 94 | } 95 | else if (typeof options === 'object') { 96 | filename = options.filename || filename; 97 | } 98 | 99 | if (typeof options === 'object' && typeof options.chunkCallback === 'function') { 100 | options.chunkCallback(this.read_file(filename)); 101 | if (typeof options.endCallback === 'function') { 102 | options.endCallback(); 103 | } 104 | } else { 105 | return this.read_file(filename); 106 | } 107 | }; 108 | 109 | /** 110 | * @inheritDoc 111 | */ 112 | jscc.ioRhino.prototype.write_output = function(options) { 113 | var text = ""; 114 | var callback = function() { 115 | }; 116 | var filename = ""; 117 | if (typeof options === 'string') { 118 | text = options; 119 | } else if (typeof options === 'object') { 120 | if (typeof options.text === 'string') { 121 | text = options.text; 122 | } 123 | if (typeof options.destination === 'string') { 124 | filename = options.destination; 125 | } 126 | if (typeof options.callback === 'function') { 127 | callback = options.callback; 128 | } 129 | } 130 | 131 | if (filename === "") { 132 | java.lang.System.out.print(text); 133 | } else { 134 | this.write_file(filename, text); 135 | } 136 | callback(); 137 | }; 138 | 139 | /** 140 | * @inheritDoc 141 | */ 142 | jscc.ioRhino.prototype.write_debug = function(text) { 143 | java.lang.System.out.print(text); 144 | }; 145 | 146 | /** 147 | * @inheritDoc 148 | */ 149 | jscc.ioRhino.prototype.exit = function(exitCode) { 150 | if (typeof exitCode !== "number") { 151 | exitCode = 0; 152 | } 153 | java.lang.System.exit(exitCode); 154 | }; 155 | 156 | /** 157 | * @module jscc/io/io 158 | */ 159 | return new jscc.ioRhino(); 160 | })); 161 | -------------------------------------------------------------------------------- /lib/jscc/io/ioSpiderMonkey.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Universal module definition for SpiderMonkey version of io module 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(['../global'], factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(require('../global')); 10 | } else { 11 | root.io = factory(root.global); 12 | } 13 | }(this, function(global) { 14 | // TODO: replace file functions, as SpiderMonkey does not handle files. 15 | var retVal = { 16 | _error: function(msg) { 17 | if (global.show_errors) { 18 | print("/*--- error: " + msg + " */"); 19 | } 20 | global.errors++; 21 | }, 22 | 23 | _warning: function(msg) { 24 | if (global.show_warnings) { 25 | print("/*--- warning: " + msg + " */"); 26 | } 27 | global.warnings++; 28 | }, 29 | 30 | _print: function(txt) { 31 | print(txt); 32 | }, 33 | 34 | _quit: function(exitcode) { 35 | quit(exitcode); 36 | }, 37 | 38 | read_file: function(file) { 39 | var src = read(file); 40 | if (!src) { 41 | retVal._error("unable to open file '" + file + "'"); 42 | quit(1); 43 | } 44 | return src; 45 | }, 46 | 47 | write_file: function(file, content) { 48 | // Not supported 49 | }, 50 | 51 | get_arguments: function() { 52 | return []; // TODO 53 | } 54 | }; 55 | return retVal; 56 | })); 57 | -------------------------------------------------------------------------------- /lib/jscc/io/ioV8.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Universal module definition for V8 version of io module. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(['../global'], factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(require('../global')); 10 | } else { 11 | root.io = factory(root.global); 12 | } 13 | }(this, function(global) { 14 | var retVal = { 15 | _error: function(msg) { 16 | if (global.show_errors) { 17 | print("error: " + global.file + ": " + msg); 18 | } 19 | global.errors++; 20 | }, 21 | 22 | _warning: function(msg) { 23 | if (global.show_warnings) { 24 | print("warning: " + global.file + ": " + msg); 25 | } 26 | global.warnings++; 27 | }, 28 | 29 | _print: function(txt) { 30 | print(txt); 31 | }, 32 | 33 | _quit: function(exitcode) { 34 | quit(exitcode); 35 | }, 36 | 37 | read_file: function(file) { 38 | var src = new String(); 39 | 40 | if (file_exists(file)) { 41 | src = file_read(file); 42 | } else { 43 | retVal._error("unable to open file '" + file + "'"); 44 | quit(); 45 | } 46 | 47 | return src; 48 | }, 49 | 50 | write_file: function(file, content) { 51 | var f = file_write(file, content); 52 | 53 | if (!f) { 54 | retVal._error("unable to write '" + file + "'"); 55 | return false; 56 | } 57 | 58 | return true; 59 | }, 60 | 61 | args_global_var: arguments, 62 | 63 | get_arguments: function() { 64 | return retVal.args_global_var; 65 | } 66 | }; 67 | return retVal; 68 | })); 69 | -------------------------------------------------------------------------------- /lib/jscc/lexdbg.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for lexdbg. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(['require', './global', './io/io', './enums/EDGE'], factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(require); 10 | } else { 11 | root.jscclexdbg = factory(function(mod) { 12 | return root["jscc" + mod.split("/").pop()]; 13 | }); 14 | } 15 | }(this, 16 | /** 17 | * @param {reqParameter} require 18 | * @param {...*} others 19 | * @returns {jscc.lexdbg} 20 | */ 21 | function(require, others) { 22 | //>>excludeStart("closure", pragmas.closure); 23 | var jscc = {}; 24 | var has = /** @type {hasObject} */ (require("./localHas")); 25 | //>>excludeEnd("closure"); 26 | var io, global = /** @type {jscc.global} */ (require("./global")), 27 | EDGE = require("./enums/EDGE"); 28 | 29 | /** 30 | * @suppress {uselessCode} 31 | */ 32 | (function() { 33 | if (has("node")) { 34 | io = /** @type {jscc.io} */ (require("./io/ioNode")); 35 | } else { 36 | io = /** @type {jscc.io} */ (require("./io/io")); 37 | } 38 | })(); 39 | 40 | /** 41 | * Debugging-output functions for automata. 42 | * @module {jscc.lexdbg} jscc/lexdbg 43 | * @requires module:jscc/global 44 | * @requires module:jscc/io/io 45 | */ 46 | /** 47 | * @constructor 48 | */ 49 | jscc.lexdbg = function() { 50 | }; 51 | jscc.lexdbg.prototype = { 52 | /** 53 | * Prints debugging information about the contents of the 54 | * {@link jscc.global.nfa_states.value} array. 55 | * @memberof jscc.lexdbg 56 | */ 57 | print_nfa: function() { 58 | io.write_debug("Pos\tType\t\tfollow\t\tfollow2\t\taccept"); 59 | io.write_debug("-----------------------------------------------------------------------"); 60 | for (var i = 0; i < global.nfa_states.value.length; i++) { 61 | io.write_debug(i + "\t" + ((global.nfa_states.value[i].edge == EDGE.FREE) ? "FREE" : 62 | ((global.nfa_states.value[i].edge == EDGE.EPSILON) ? "EPSILON" : "CHAR")) + 63 | "\t\t" + 64 | ((global.nfa_states.value[i].edge != EDGE.FREE && 65 | global.nfa_states.value[i].follow > -1) ? 66 | global.nfa_states.value[i].follow : 67 | "") + "\t\t" + 68 | ((global.nfa_states.value[i].edge != EDGE.FREE && 69 | global.nfa_states.value[i].follow2 > -1) ? 70 | global.nfa_states.value[i].follow2 : 71 | "") + "\t\t" + 72 | ((global.nfa_states.value[i].edge != EDGE.FREE && 73 | global.nfa_states.value[i].accept > -1) ? 74 | global.nfa_states.value[i].accept : 75 | "")); 76 | 77 | if (global.nfa_states.value[i].edge == EDGE.CHAR) { 78 | var chars = ""; 79 | for (var j = global.MIN_CHAR; j < global.MAX_CHAR; j++) { 80 | if (global.nfa_states.value[i].ccl.get(j)) { 81 | chars += String.fromCharCode(j); 82 | if (chars.length == 10) { 83 | io.write_debug("\t" + chars); 84 | chars = ""; 85 | } 86 | } 87 | } 88 | 89 | if (chars.length > 0) { 90 | io.write_debug("\t" + chars); 91 | } 92 | } 93 | } 94 | io.write_debug(""); 95 | }, 96 | 97 | /** 98 | * Prints debugging information about the provided array of 99 | * Dfa objects. 100 | * @param {Array} dfa_states - The states for which to 101 | * print debugging information. 102 | * @memberof jscc.lexdbg 103 | */ 104 | print_dfa: function(dfa_states) { 105 | var str = ""; 106 | var chr_cnt = 0; 107 | for (var i = 0; i < dfa_states.length; i++) { 108 | str = i + " => ("; 109 | 110 | chr_cnt = 0; 111 | for (var j = 0; j < dfa_states[i].line.length; j++) { 112 | if (dfa_states[i].line[j] > -1) { 113 | str += " >" + String.fromCharCode(j) + "<," + dfa_states[i].line[j] + " "; 114 | chr_cnt++; 115 | 116 | if ((chr_cnt % 5) == 0) { 117 | str += "\n "; 118 | } 119 | } 120 | } 121 | 122 | str += ") " + dfa_states[i].accept; 123 | io.write_debug(str); 124 | } 125 | } 126 | }; 127 | return new jscc.lexdbg(); 128 | })); 129 | -------------------------------------------------------------------------------- /lib/jscc/localHas.js: -------------------------------------------------------------------------------- 1 | (function(root, factory) { 2 | /* istanbul ignore next */ 3 | if (typeof define === 'function' && define.amd) { 4 | define(["require", "has"], factory); 5 | } else if (typeof module === 'object' && module.exports) { 6 | module.exports = factory(require); 7 | } else { 8 | root.jscclocalHas = factory(function() { 9 | // We're only using this module for Node, which clearly isn't 10 | // present here. So, just return a function that returns 11 | // false. 12 | return function() { 13 | return false; 14 | }; 15 | }); 16 | } 17 | }(this, 18 | /** 19 | * @param {reqParameter} require 20 | * @param {...*} others 21 | * @returns {hasObject} 22 | */ 23 | function(require, others) { 24 | var has; 25 | try { 26 | has = /** @type {hasObject} */ (require("has")); 27 | } catch (e) { 28 | has = /** @type {hasObject} */ (require("../../volo/has")); 29 | } 30 | 31 | has.add("node", function() { 32 | return typeof process === "object" && typeof process.version === "string" && 33 | (typeof define !== "function" || !define.amd); 34 | }, false); 35 | 36 | return has; 37 | })); -------------------------------------------------------------------------------- /lib/jscc/log/log.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Interface for engine-specific logging modules. 3 | * @interface 4 | */ 5 | jscc.log = function() { 6 | 7 | }; 8 | jscc.log.prototype = { 9 | /** 10 | * Logs a message at the fatal level. 11 | * @param {string} msg - The message to log. 12 | */ 13 | fatal: function(msg) { 14 | }, 15 | /** 16 | * Logs a message at the error level. 17 | * @param {string} msg - The message to log. 18 | */ 19 | error: function(msg) { 20 | }, 21 | /** 22 | * Logs a message at the warning level. 23 | * @param {string} msg - The message to log. 24 | */ 25 | warn: function(msg) { 26 | }, 27 | /** 28 | * Logs a message at the info level. 29 | * @param {string} msg - The message to log. 30 | */ 31 | info: function(msg) { 32 | }, 33 | /** 34 | * Logs a message at the debug level. 35 | * @param {string} msg - The message to log. 36 | */ 37 | debug: function(msg) { 38 | }, 39 | /** 40 | * Logs a message at the trace level. 41 | * @param {string} msg - The message to log. 42 | */ 43 | trace: function(msg) { 44 | }, 45 | /** 46 | * Sets the minimum level to log. This function 47 | * may not have an effect at all times with all 48 | * loggers. 49 | * @param {jscc.enums.LOG_LEVEL} level - The 50 | * minimum level to log. 51 | */ 52 | setLevel: function(level) { 53 | } 54 | }; 55 | 56 | -------------------------------------------------------------------------------- /lib/jscc/log/logBrowser.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for logging in browsers. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(['require', '../global', '../enums/LOG_LEVEL'], factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(require); 10 | } else { 11 | root.jscclog = factory(function(mod) { 12 | return root["jscc" + mod.split("/").pop()]; 13 | }); 14 | } 15 | }(this, function(/** reqParameter */ require) { 16 | //>>excludeStart("closure", pragmas.closure); 17 | var jscc = {}; 18 | //>>excludeEnd("closure"); 19 | var global = /** @type {jscc.global} */ (require("../global")), 20 | LOG_LEVEL = require("../enums/LOG_LEVEL"); 21 | 22 | var innerConsole = console || Console || {}; 23 | innerConsole.log = innerConsole.log || function(msg) { 24 | }; 25 | innerConsole.warn = innerConsole.warn || innerConsole.log || function(msg) { 26 | }; 27 | innerConsole.error = innerConsole.error || innerConsole.log || function(msg) { 28 | }; 29 | innerConsole.info = innerConsole.info || innerConsole.log || function(msg) { 30 | }; 31 | innerConsole.trace = innerConsole.trace || innerConsole.log || function(msg) { 32 | }; 33 | 34 | /** 35 | * @constructor 36 | * @implements {jscc.log} 37 | */ 38 | jscc.logBrowser = function() { 39 | this._level = LOG_LEVEL.WARN; 40 | }; 41 | 42 | /** 43 | * @type {jscc.enums.LOG_LEVEL} 44 | * @private 45 | */ 46 | jscc.logBrowser.prototype._level = LOG_LEVEL.WARN; 47 | 48 | /** 49 | * @inheritDoc 50 | */ 51 | jscc.logBrowser.prototype.fatal = function(msg) { 52 | if (this._level <= LOG_LEVEL.FATAL) { 53 | innerConsole.error(msg); 54 | } 55 | global.errors++; 56 | }; 57 | 58 | /** 59 | * @inheritDoc 60 | */ 61 | jscc.logBrowser.prototype.error = function(msg) { 62 | if (this._level <= LOG_LEVEL.ERROR) { 63 | innerConsole.error(msg); 64 | } 65 | global.errors++; 66 | }; 67 | 68 | /** 69 | * @inheritDoc 70 | */ 71 | jscc.logBrowser.prototype.warn = function(msg) { 72 | if (this._level <= LOG_LEVEL.WARN) { 73 | innerConsole.warn(msg); 74 | } 75 | global.warnings++; 76 | }; 77 | 78 | /** 79 | * @inheritDoc 80 | */ 81 | jscc.logBrowser.prototype.info = function(msg) { 82 | if (this._level <= LOG_LEVEL.INFO) { 83 | innerConsole.info(msg); 84 | } 85 | }; 86 | 87 | /** 88 | * @inheritDoc 89 | */ 90 | jscc.logBrowser.prototype.debug = function(msg) { 91 | if (this._level <= LOG_LEVEL.DEBUG) { 92 | innerConsole.log(msg); 93 | } 94 | }; 95 | 96 | /** 97 | * @inheritDoc 98 | */ 99 | jscc.logBrowser.prototype.trace = function(msg) { 100 | if (this._level <= LOG_LEVEL.TRACE) { 101 | innerConsole.trace(msg); 102 | } 103 | }; 104 | 105 | /** 106 | * @inheritDoc 107 | */ 108 | jscc.logBrowser.prototype.setLevel = function(level) { 109 | this._level = level; 110 | }; 111 | 112 | /** 113 | * @module jscc/log/log 114 | */ 115 | return new jscc.logBrowser(); 116 | })); 117 | -------------------------------------------------------------------------------- /lib/jscc/log/logJava.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for logging in both Rhino and Nashorn. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(['require', '../global', '../enums/LOG_LEVEL'], factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(require); 10 | } else { 11 | root.jscclog = factory(function(mod) { 12 | return root["jscc" + mod.split("/").pop()]; 13 | }); 14 | } 15 | }(this, function(/** reqParameter */ require) { 16 | //>>excludeStart("closure", pragmas.closure); 17 | var jscc = {}; 18 | //>>excludeEnd("closure"); 19 | var global = /** @type {jscc.global} */ (require("../global")), 20 | LOG_LEVEL = require("../enums/LOG_LEVEL"); 21 | 22 | var /** @type {function(new:java.util.logging.ConsoleHandler)} */ ConsoleHandler, 23 | /** @type {java.util.logging.Level} */ javaSevere, 24 | /** @type {java.util.logging.Level} */ javaWarning, 25 | /** @type {java.util.logging.Level} */ javaInfo, 26 | /** @type {java.util.logging.Level} */ javaFine, 27 | /** @type {java.util.logging.Level} */ javaFiner; 28 | //>>includeStart("nashorn", pragmas.nashorn); 29 | var javaLevel = /** @type {java.util.logging.Level} */ (Java.type("java.util.logging.Level")); 30 | javaSevere = javaLevel.SEVERE; 31 | javaWarning = javaLevel.WARNING; 32 | javaInfo = javaLevel.INFO; 33 | javaFine = javaLevel.FINE; 34 | javaFiner = javaLevel.FINER; 35 | ConsoleHandler = /** @type {function(new:java.util.logging.ConsoleHandler)} */ 36 | (Java.type("java.util.logging.ConsoleHandler")); 37 | //>>includeEnd("nashorn"); 38 | //>>excludeStart("nashorn", pragmas.nashorn); 39 | javaSevere = java.util.logging.Level.SEVERE; 40 | javaWarning = java.util.logging.Level.WARNING; 41 | javaInfo = java.util.logging.Level.INFO; 42 | javaFine = java.util.logging.Level.FINE; 43 | javaFiner = java.util.logging.Level.FINER; 44 | ConsoleHandler = java.util.logging.ConsoleHandler; 45 | //>>excludeEnd("nashorn"); 46 | 47 | function resolveModules() { 48 | global = global || require("../global"); 49 | } 50 | 51 | /** 52 | * @implements {jscc.log} 53 | * @constructor 54 | */ 55 | jscc.logJava = function() { 56 | //>>includeStart("nashorn", pragmas.nashorn); 57 | this._log = /** @type {java.util.logging.Logger} */ (Java.type("java.util.logging.Logger").getLogger("jscc")); 58 | //>>includeEnd("nashorn"); 59 | //>>excludeStart("nashorn", pragmas.nashorn); 60 | this._log = java.util.logging.Logger.getLogger("jscc"); 61 | //>>excludeEnd("nashorn"); 62 | var handler = new ConsoleHandler(); 63 | handler.setLevel(javaFiner); 64 | this._log.addHandler(handler); 65 | }; 66 | 67 | /** 68 | * @type {java.util.logging.Logger} 69 | * @private 70 | */ 71 | jscc.logJava.prototype._log = null; 72 | 73 | /** 74 | * @param {java.util.logging.Level} javaLevel 75 | * @param {string} msg 76 | * @private 77 | */ 78 | jscc.logJava.prototype._write = function(javaLevel, msg) { 79 | //>>includeStart("nashorn", pragmas.nashorn); 80 | this._log["log(java.util.logging.Level, java.lang.String)"](javaLevel, msg); 81 | //>>includeEnd("nashorn"); 82 | //>>excludeStart("nashorn", pragmas.nashorn); 83 | this._log.log(javaLevel, msg); 84 | //>>excludeEnd("nashorn"); 85 | }; 86 | 87 | /** 88 | * @inheritDoc 89 | */ 90 | jscc.logJava.prototype.fatal = function(msg) { 91 | resolveModules(); 92 | this._write(javaSevere, msg); 93 | global.errors++; 94 | }; 95 | 96 | /** 97 | * @inheritDoc 98 | */ 99 | jscc.logJava.prototype.error = function(msg) { 100 | resolveModules(); 101 | this._write(javaSevere, msg); 102 | global.errors++; 103 | }; 104 | 105 | /** 106 | * @inheritDoc 107 | */ 108 | jscc.logJava.prototype.warn = function(msg) { 109 | resolveModules(); 110 | this._write(javaWarning, msg); 111 | global.warnings++; 112 | }; 113 | 114 | /** 115 | * @inheritDoc 116 | */ 117 | jscc.logJava.prototype.info = function(msg) { 118 | this._write(javaInfo, msg); 119 | }; 120 | 121 | /** 122 | * @inheritDoc 123 | */ 124 | jscc.logJava.prototype.debug = function(msg) { 125 | this._write(javaFine, msg); 126 | }; 127 | 128 | /** 129 | * @inheritDoc 130 | */ 131 | jscc.logJava.prototype.trace = function(msg) { 132 | this._write(javaFiner, msg); 133 | }; 134 | 135 | /** 136 | * @inheritDoc 137 | */ 138 | jscc.logJava.prototype.setLevel = function(level) { 139 | switch (level) { 140 | case LOG_LEVEL.FATAL: 141 | case LOG_LEVEL.ERROR: 142 | this._log.setLevel(javaSevere); 143 | break; 144 | case LOG_LEVEL.WARN: 145 | this._log.setLevel(javaWarning); 146 | break; 147 | case LOG_LEVEL.INFO: 148 | this._log.setLevel(javaInfo); 149 | break; 150 | case LOG_LEVEL.DEBUG: 151 | this._log.setLevel(javaFine); 152 | break; 153 | case LOG_LEVEL.TRACE: 154 | this._log.setLevel(javaFiner); 155 | break; 156 | default: 157 | this._log.setLevel(javaWarning); 158 | break; 159 | } 160 | }; 161 | 162 | /** 163 | * @module {jscc.log} jscc/log/log 164 | */ 165 | return new jscc.logJava(); 166 | })); 167 | -------------------------------------------------------------------------------- /lib/jscc/log/logNode.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for logging in Node. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(['require', '../global', '../enums/LOG_LEVEL'], factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(require); 10 | } else { 11 | root.jscclog = factory(function(mod) { 12 | return root["jscc" + mod.split("/").pop()]; 13 | }); 14 | } 15 | }(this, 16 | /** 17 | * @param {reqParameter} require 18 | * @param {...*} others 19 | * @returns {jscc.log} 20 | */ 21 | function(require, others) { 22 | //>>excludeStart("closure", pragmas.closure); 23 | var jscc = {}; 24 | //>>excludeEnd("closure"); 25 | var global = /** @type {jscc.global} */ (require("../global")), 26 | LOG_LEVEL = require("../enums/LOG_LEVEL"); 27 | 28 | /** 29 | * @constructor 30 | * @implements {jscc.log} 31 | */ 32 | jscc.logNode = function() { 33 | this._level = LOG_LEVEL.WARN; 34 | }; 35 | 36 | /** 37 | * @type {jscc.enums.LOG_LEVEL} 38 | * @private 39 | */ 40 | jscc.logNode.prototype._level = LOG_LEVEL.WARN; 41 | 42 | /** 43 | * @inheritDoc 44 | */ 45 | jscc.logNode.prototype.fatal = function(msg) { 46 | console.error(msg); 47 | global.errors++; 48 | }; 49 | 50 | /** 51 | * @inheritDoc 52 | */ 53 | jscc.logNode.prototype.error = function(msg) { 54 | if (this._level <= LOG_LEVEL.ERROR) { 55 | console.error(msg); 56 | } 57 | global.errors++; 58 | }; 59 | 60 | /** 61 | * @inheritDoc 62 | */ 63 | jscc.logNode.prototype.warn = function(msg) { 64 | if (this._level <= LOG_LEVEL.WARN) { 65 | console.warn(msg); 66 | } 67 | global.warnings++; 68 | }; 69 | 70 | /** 71 | * @inheritDoc 72 | */ 73 | jscc.logNode.prototype.info = function(msg) { 74 | if (this._level <= LOG_LEVEL.INFO) { 75 | console.info(msg); 76 | } 77 | }; 78 | 79 | /** 80 | * @inheritDoc 81 | */ 82 | jscc.logNode.prototype.debug = function(msg) { 83 | if (this._level <= LOG_LEVEL.DEBUG) { 84 | console.log(msg); 85 | } 86 | }; 87 | 88 | /** 89 | * @inheritDoc 90 | */ 91 | jscc.logNode.prototype.trace = function(msg) { 92 | if (this._level <= LOG_LEVEL.TRACE) { 93 | console.trace(msg); 94 | } 95 | }; 96 | 97 | /** 98 | * @inheritDoc 99 | */ 100 | jscc.logNode.prototype.setLevel = function(level) { 101 | this._level = level; 102 | }; 103 | 104 | /** 105 | * @module jscc/log/log 106 | */ 107 | return new jscc.logNode(); 108 | })); 109 | -------------------------------------------------------------------------------- /lib/jscc/nfaStates.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Universal module definition for NFAStates (previously in global.js). 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(['require', './bitset', './enums/EDGE', './classes/Nfa'], factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(require); 10 | } else { 11 | root.jsccnfaStates = factory(function(mod) { 12 | return root["jscc" + mod.split("/").pop()]; 13 | }); 14 | } 15 | }(this, 16 | /** 17 | * @param {reqParameter} require 18 | * @param {...*} others 19 | * @returns {function(new:jscc.NFAStates)} 20 | */ 21 | function(require, others) { 22 | //>>excludeStart("closure", pragmas.closure); 23 | var jscc = {}; 24 | //>>excludeEnd("closure"); 25 | 26 | var BitSet, 27 | tmpBitSet, 28 | EDGE = require("./enums/EDGE"), 29 | Nfa = /** @type {function(new:jscc.classes.Nfa, ?NfaOptions=)} */ (require("./classes/Nfa")); 30 | //>>excludeStart("closure", pragmas.closure); 31 | var has = /** @type {hasObject} */ (require("./localHas")); 32 | //>>excludeEnd("closure"); 33 | 34 | /** 35 | * @suppress {uselessCode} 36 | */ 37 | (function() { 38 | if (has("node")) { 39 | tmpBitSet = require("./bitset/BitSet32"); 40 | } else { 41 | tmpBitSet = require("./bitset"); 42 | } 43 | })(); 44 | BitSet = /** @type {function(new:jscc.bitset)} */ (tmpBitSet); 45 | 46 | /** 47 | * Module with a class that creates and stores Nfa objects. 48 | * @module {jscc.NFAStates} jscc/nfaStates 49 | * @constructor 50 | */ 51 | jscc.NFAStates = function() { 52 | }; 53 | /** 54 | * The inner array of Nfa objects. 55 | * @type {!Array} 56 | */ 57 | jscc.NFAStates.prototype.value = []; 58 | /** 59 | * Finds an empty Nfa already in the value array if possible, 60 | * and returns its index. Otherwise, creates a new Nfa object 61 | * and returns its index within the value array. 62 | * @returns {number} The index of the new or recycled Nfa 63 | * object within the value array. 64 | */ 65 | jscc.NFAStates.prototype.create = function() { 66 | var nfa; 67 | var i; 68 | // Use an empty item if available, else create a new one... 69 | for (i = 0; i < this.value.length; i++) { 70 | if (this.value[i].edge === EDGE.FREE) { 71 | break; 72 | } 73 | } 74 | 75 | if (i == this.value.length) { 76 | nfa = new Nfa(); 77 | this.value.push(nfa); 78 | } else { 79 | nfa = this.value[i]; 80 | } 81 | nfa.edge = EDGE.EPSILON; 82 | nfa.ccl = new BitSet(); 83 | nfa.accept = -1; 84 | nfa.follow = -1; 85 | nfa.follow2 = -1; 86 | nfa.weight = -1; 87 | return i; 88 | }; 89 | return jscc.NFAStates; 90 | })); -------------------------------------------------------------------------------- /lib/jscc/util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Universal module definition for util. 3 | */ 4 | (function(root, factory) { 5 | /* istanbul ignore next */ 6 | if (typeof define === 'function' && define.amd) { 7 | define(['require', './enums/LOG_LEVEL'], factory); 8 | } else if (typeof module === 'object' && module.exports) { 9 | module.exports = factory(require); 10 | } else { 11 | root.jsccutil = 12 | factory(function(mod) { 13 | return root["jscc" + mod.split("/").pop()]; 14 | }); 15 | } 16 | }(this, 17 | /** 18 | * @param {reqParameter} require 19 | * @param {...*} others 20 | * @returns {jscc.util} 21 | */ 22 | function(require, others) { 23 | //>>excludeStart("closure", pragmas.closure); 24 | var jscc = {}; 25 | //>>excludeEnd("closure"); 26 | var LOG_LEVEL = require("./enums/LOG_LEVEL"); 27 | 28 | /** 29 | * Utility functions. 30 | * @module {jscc.util} jscc/util 31 | */ 32 | /** 33 | * @constructor 34 | */ 35 | jscc.util = function() { 36 | }; 37 | jscc.util.prototype = { 38 | /** 39 | * Unions the content of two arrays. 40 | * @template T 41 | * @param {!Array} dest_array - The destination array. 42 | * @param {!Array} src_array - The source array. Elements 43 | * that are not in dest_array but in src_array are copied 44 | * to dest_array. 45 | * @returns {!Array} The destination array, the union of 46 | * both input arrays. 47 | * @author Jan Max Meyer 48 | * @memberof jscc.util 49 | */ 50 | union: function(dest_array, src_array) { 51 | var i, j; 52 | for (i = 0; i < src_array.length; i++) { 53 | for (j = 0; j < dest_array.length; j++) { 54 | if (src_array[i] == dest_array[j]) { 55 | break; 56 | } 57 | } 58 | 59 | if (j == dest_array.length) { 60 | dest_array.push(src_array[i]); 61 | } 62 | } 63 | 64 | return dest_array; 65 | }, 66 | 67 | /** 68 | * Gets the string name (in all caps) of the 69 | * {@link jscc.enums.LOG_LEVEL} value provided. 70 | * @param {jscc.enums.LOG_LEVEL} level - The 71 | * LOG_LEVEL value 72 | * @returns {string} The name of the log level in all caps 73 | * @memberof jscc.Util 74 | */ 75 | log_level_string: function(level) { 76 | switch (level) { 77 | case LOG_LEVEL.FATAL: 78 | return "FATAL"; 79 | case LOG_LEVEL.ERROR: 80 | return "ERROR"; 81 | case LOG_LEVEL.WARN: 82 | return "WARN"; 83 | case LOG_LEVEL.INFO: 84 | return "INFO"; 85 | case LOG_LEVEL.DEBUG: 86 | return "DEBUG"; 87 | case LOG_LEVEL.TRACE: 88 | return "TRACE"; 89 | default: 90 | return ""; 91 | } 92 | }, 93 | 94 | /** 95 | * Gets the {@link jscc.enums.LOG_LEVEL} value 96 | * corresponding to the provided string. If the string 97 | * is empty or invalid, returns 98 | * {@link jscc.enums.LOG_LEVEL.WARN} as a default. 99 | * @param {string} levelString - The name of the log level. 100 | * @returns {jscc.enums.LOG_LEVEL} The corresponding 101 | * LOG_LEVEL value, defaulting to WARN. 102 | */ 103 | log_level_value: function(levelString) { 104 | switch ((levelString || "").trim().toUpperCase()) { 105 | case "FATAL": 106 | return LOG_LEVEL.FATAL; 107 | case "ERROR": 108 | return LOG_LEVEL.ERROR; 109 | case "WARN": 110 | return LOG_LEVEL.WARN; 111 | case "INFO": 112 | return LOG_LEVEL.INFO; 113 | case "DEBUG": 114 | return LOG_LEVEL.DEBUG; 115 | case "TRACE": 116 | return LOG_LEVEL.TRACE; 117 | default: 118 | return LOG_LEVEL.WARN; 119 | } 120 | } 121 | }; 122 | return new jscc.util(); 123 | })); 124 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | (function(root, factory) { 2 | /* istanbul ignore next */ 3 | if (typeof define === 'function' && define.amd) { 4 | define(["require", "./lib/jscc/main"], factory); 5 | } else if (typeof module === 'object' && module.exports) { 6 | module.exports = factory(require); 7 | } else { 8 | root.jsccmain = factory(function() { 9 | return root.jscc; 10 | }); 11 | } 12 | }(this, 13 | /** 14 | * @param {reqParameter} require 15 | * @param {...*} others 16 | * @returns {function(?mainOptions=)} 17 | */ 18 | function(require, others) { 19 | var main = /** @type {function(?mainOptions=)} */ (require("./lib/jscc/main")); 20 | return main; 21 | })); -------------------------------------------------------------------------------- /npm-bin-template.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var runner = "##RUNNER##", 3 | child_process = require("child_process"), 4 | path = require("path"), 5 | execName = "jscc-" + runner + (process.platform === "win32" ? ".bat" : ".sh"), 6 | args = process.argv.slice(2); 7 | try { 8 | child_process.execSync("\"" + path.join(__dirname, execName) + "\" " + args.join(" "), { stdio: "inherit" }); 9 | process.exit(0); 10 | } catch (e) { 11 | console.error(e.message); 12 | process.exit(1); 13 | } 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jscc-parser", 3 | "version": "0.40.2", 4 | "main": "main.js", 5 | "description": "A LALR(1) Parser Generator for JavaScript written in JavaScript.", 6 | "license": "BSD-3-Clause", 7 | "keywords": [ 8 | "jscc", 9 | "JS/CC", 10 | "lexer", 11 | "parser", 12 | "lexical analysis", 13 | "yacc", 14 | "lex" 15 | ], 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/abrobston/jscc.git" 19 | }, 20 | "bugs": "https://github.com/abrobston/jscc/issues", 21 | "contributors": [ 22 | { 23 | "name": "Jan Max Meyer", 24 | "email": "contact@phorward-software.com", 25 | "web": "http://jscc.phorward-software.com/" 26 | }, 27 | { 28 | "name": "Sergiy Shatunov" 29 | }, 30 | { 31 | "name": "Louis P. Santillan" 32 | }, 33 | { 34 | "name": "Andrew Brobston", 35 | "email": "andrew@brobston.com" 36 | } 37 | ], 38 | "devDependencies": { 39 | "almond": "~0.3.2", 40 | "amdclean": "~2.7.0", 41 | "amdefine": "~1.0.0", 42 | "async": "~2.6.0", 43 | "chai": "~4.1.2", 44 | "codecov": "~3.0.0", 45 | "extract-zip": "~1.6.6", 46 | "google-closure-compiler": "=20160517.0.0", 47 | "gulp": "~3.9.1", 48 | "jformatter": "~1.0.13", 49 | "jsdoc": "~3.5.5", 50 | "mocha": "~4.0.1", 51 | "nyc": "~11.3.0", 52 | "phantomjs-prebuilt": "~2.1.9", 53 | "requirejs": "~2.2.0", 54 | "requirejs-text": "~2.0.12", 55 | "rest": "^2.0.0", 56 | "sinon": "~4.1.2", 57 | "source-map": "~0.6.1", 58 | "squirejs": "~0.2.1", 59 | "temp": "~0.8.3" 60 | }, 61 | "homepage": "http://jscc.brobston.com/", 62 | "engine": [ 63 | "node", 64 | "rhino", 65 | "nashorn" 66 | ], 67 | "bin": { 68 | "jscc-browser": "./bin/npm-browser.js", 69 | "jscc-nashorn": "./bin/npm-nashorn.js", 70 | "jscc-node": "./bin/npm-node.js", 71 | "jscc-rhino": "./bin/npm-rhino.js" 72 | }, 73 | "directories": { 74 | "lib": "lib" 75 | }, 76 | "nyc": { 77 | "cache": true, 78 | "require": [ 79 | "./main" 80 | ], 81 | "exclude": [ 82 | "test/**/*.js", 83 | "asyncSupport.js", 84 | "gulpfile.js", 85 | "resolvePackageDirectories.js", 86 | "volo/**/*.js", 87 | "lib/jscc/bitset/bitset.js", 88 | "lib/jscc/bitset/BitSetBool.js", 89 | "lib/jscc/bitset/BitSetJava.js", 90 | "lib/jscc/io/io.js", 91 | "lib/jscc/io/ioBrowser.js", 92 | "lib/jscc/io/ioNashorn.js", 93 | "lib/jscc/io/ioRhino.js", 94 | "lib/jscc/io/ioSpiderMonkey.js", 95 | "lib/jscc/io/ioV8.js", 96 | "lib/jscc/log/log.js", 97 | "lib/jscc/log/logBrowser.js", 98 | "lib/jscc/log/logJava.js" 99 | ] 100 | }, 101 | "scripts": { 102 | "test": "nyc gulp test", 103 | "coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov -f coverage.lcov", 104 | "prepublish": "npm update --dev && gulp clean && gulp build" 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /require-browser-build.js: -------------------------------------------------------------------------------- 1 | ({ 2 | "mainConfigFile": "./require-browser-config.js", 3 | "baseUrl": ".", 4 | "pragmas": { 5 | "closure": true 6 | }, 7 | "has": { 8 | "node": false 9 | }, 10 | "optimize": "closure", 11 | "preserveLicenseComments": false, 12 | "generateSourceMaps": true, 13 | "closure": { 14 | "CompilerOptions": { 15 | "language": com.google.javascript.jscomp.CompilerOptions.LanguageMode.ECMASCRIPT5, 16 | "checkSymbols": true, 17 | "checkTypes": true 18 | }, 19 | "CompilationLevel": "ADVANCED_OPTIMIZATIONS", 20 | "externExportsPath": "./externs.js", 21 | "loggingLevel": "FINE" 22 | }, 23 | "name": "bin/almond", 24 | "include": ["main"], 25 | "stubModules": ["text"], 26 | "wrap": { 27 | "startFile": ["fileoverview.js", "typedef.js", "lib/jscc/io/io.js", "lib/jscc/log/log.js", "lib/jscc/bitset/bitset.js"], 28 | "endFile": ["exports.js", "exports-requireLib.js", "require-browser-config.js", "require-main.js"] 29 | }, 30 | "out": "./bin/jscc-browser.js", 31 | "logLevel": 2 32 | }) 33 | -------------------------------------------------------------------------------- /require-browser-config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * RequireJS configuration for browser environments. 3 | */ 4 | requirejs.config({ 5 | baseUrl: ".", 6 | paths: { 7 | "text": "bin/text", 8 | "requireLib": "node_modules/requirejs/require", 9 | "has": "volo/has" 10 | }, 11 | map: { 12 | "*": { 13 | "lib/jscc/io/io": "lib/jscc/io/ioBrowser", 14 | "lib/jscc/log/log": "lib/jscc/log/logBrowser", 15 | "lib/jscc/bitset": "lib/jscc/bitset/BitSet32" 16 | } 17 | }, 18 | nodeRequire: require, 19 | config: { 20 | "lib/jscc/global": { 21 | "version": "0.40.1" 22 | } 23 | } 24 | }); -------------------------------------------------------------------------------- /require-main.js: -------------------------------------------------------------------------------- 1 | require(["main"]); -------------------------------------------------------------------------------- /require-nashorn-build.js: -------------------------------------------------------------------------------- 1 | ({ 2 | "mainConfigFile": "./require-nashorn-config.js", 3 | "baseUrl": ".", 4 | "pragmas": { 5 | "closure": true, 6 | "nashorn": true 7 | }, 8 | "has": { 9 | "node": false 10 | }, 11 | "optimize": "closure", 12 | "preserveLicenseComments": false, 13 | "generateSourceMaps": true, 14 | "closure": { 15 | "CompilerOptions": { 16 | "language": com.google.javascript.jscomp.CompilerOptions.LanguageMode.ECMASCRIPT5, 17 | "checkSymbols": true, 18 | "checkTypes": true 19 | }, 20 | "CompilationLevel": "ADVANCED_OPTIMIZATIONS", 21 | "loggingLevel": "FINE", 22 | "externExportsPath": "./externs.js" 23 | }, 24 | "name": "bin/almond", 25 | "include": ["main"], 26 | "stubModules": ["text"], 27 | "wrap": { 28 | "startFile": ["fileoverview.js", "typedef.js", "global-backfills.js", "lib/jscc/io/io.js", "lib/jscc/log/log.js", "lib/jscc/bitset/bitset.js"], 29 | "endFile": ["exports.js", "exports-require.js", "require-nashorn-config.js", "require-main.js"] 30 | }, 31 | "out": "./bin/jscc-nashorn.js", 32 | "logLevel": 2 33 | }) -------------------------------------------------------------------------------- /require-nashorn-config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * RequireJS configuration for Nashorn. 3 | */ 4 | requirejs.config({ 5 | baseUrl: ".", 6 | paths: { 7 | "text": "bin/text", 8 | "has": "volo/has" 9 | }, 10 | map: { 11 | "*": { 12 | "lib/jscc/io/io": "lib/jscc/io/ioNashorn", 13 | "lib/jscc/log/log": "lib/jscc/log/logJava", 14 | "lib/jscc/bitset": "lib/jscc/bitset/BitSetJava" 15 | } 16 | }, 17 | nodeRequire: require, 18 | config: { 19 | "lib/jscc/global": { 20 | "version": "0.40.1" 21 | } 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /require-node-build.js: -------------------------------------------------------------------------------- 1 | ({ 2 | "mainConfigFile": "./require-node-config.js", 3 | "baseUrl": ".", 4 | "pragmas": { 5 | "closure": true, 6 | "amdclean": true, 7 | "node": true 8 | }, 9 | "has": { 10 | "amdclean": true, 11 | "node": true 12 | }, 13 | "optimize": "closure", 14 | "preserveLicenseComments": false, 15 | "generateSourceMaps": true, 16 | "closure": { 17 | "CompilerOptions": { 18 | "language": com.google.javascript.jscomp.CompilerOptions.LanguageMode.ECMASCRIPT5, 19 | "checkSymbols": true, 20 | "checkTypes": true 21 | }, 22 | "CompilationLevel": "ADVANCED_OPTIMIZATIONS", 23 | "loggingLevel": "FINE", 24 | "externExportsPath": "./externsWithRequire.js" 25 | }, 26 | "name": "main", 27 | "wrap": { 28 | "startFile": ["fileoverview-node.js", "typedef.js", "amdclean-node-globals.js", "lib/jscc/io/io.js", 29 | "lib/jscc/log/log.js", "lib/jscc/bitset/bitset.js"], 30 | "endFile": ["exports.js"] 31 | }, 32 | "out": "./bin/jscc-node.js", 33 | "logLevel": 2, 34 | "stubModules": ["text", "has"], 35 | "onModuleBundleComplete": function(data) { 36 | var isNode = typeof process === "object", 37 | isNashorn = typeof Java !== "undefined" && typeof Java.type === "function", 38 | isRhino = typeof java !== "undefined" && !isNashorn; 39 | 40 | (function(mainPath) { 41 | if (isNode) { 42 | var path = require("path"); 43 | var rjsPath = path.join(__dirname, "node_modules", ".bin", 44 | process.platform === "win32" ? "r.js.cmd" : "r.js"); 45 | var stderrLines = []; 46 | var stderrStream = new require("stream").Writable({ 47 | write: function(chunk, encoding, next) { 48 | if (Buffer.isBuffer(chunk)) { 49 | stderrLines.push(chunk.toString("utf8")); 50 | } else { 51 | stderrLines.push(chunk); 52 | } 53 | next(); 54 | } 55 | } 56 | ); 57 | stderrStream.on("finish", function() { 58 | console.log("Standard error:"); 59 | console.log(stderrLines.join(require("os").EOL)); 60 | }); 61 | 62 | var stdOut = 63 | require("child_process") 64 | .execSync( 65 | "\"" + rjsPath + "\" \"" + path.join(__dirname, "run-amdclean.js") + "\" \"" + mainPath + 66 | "\"", { 67 | stdio: ["inherit", "pipe", stderrStream], 68 | encoding: "utf8" 69 | }); 70 | console.log("Standard output:" + require("os").EOL + stdOut); 71 | return; 72 | } 73 | if (isRhino) { 74 | var exitCode = 75 | org.mozilla.javascript.tools.shell.Main.exec( 76 | ["./node_modules/requirejs/bin/r.js", "./run-amdclean.js", mainPath]); 77 | if (exitCode !== 0) { 78 | quit(exitCode); 79 | } 80 | return; 81 | } 82 | if (isNashorn) { 83 | loadWithNewGlobal("./node_modules/requirejs/bin/r.js", "./run-amdclean.js", mainPath); 84 | // We need to wait until the various asynchronous threads all complete, since this 85 | // isn't Node. 86 | var commonPool = Java.type("java.util.concurrent.ForkJoinPool").commonPool(); 87 | var minuteUnit = Java.type("java.util.concurrent.TimeUnit").MINUTES; 88 | commonPool.awaitQuiescence(9, minuteUnit); 89 | } 90 | })(data.path); 91 | } 92 | }) 93 | -------------------------------------------------------------------------------- /require-node-config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * RequireJS configuration for Node. 3 | */ 4 | requirejs.config({ 5 | baseUrl: ".", 6 | paths: { 7 | "text": "bin/text", 8 | "json": "volo/json", 9 | "has": "volo/has" 10 | }, 11 | map: { 12 | "*": { 13 | "lib/jscc/io/io": "lib/jscc/io/ioNode", 14 | "lib/jscc/log/log": "lib/jscc/log/logNode", 15 | "lib/jscc/bitset": "lib/jscc/bitset/BitSet32" 16 | } 17 | }, 18 | nodeRequire: require, 19 | config: { 20 | "lib/jscc/global": { 21 | "version": "0.40.1" 22 | }, 23 | "env": "node" 24 | } 25 | }); -------------------------------------------------------------------------------- /require-rhino-build.js: -------------------------------------------------------------------------------- 1 | ({ 2 | "mainConfigFile": "./require-rhino-config.js", 3 | "baseUrl": ".", 4 | "pragmas": { 5 | "closure": true 6 | }, 7 | "has": { 8 | "node": false 9 | }, 10 | "optimize": "closure", 11 | "preserveLicenseComments": false, 12 | "generateSourceMaps": true, 13 | "closure": { 14 | "CompilerOptions": { 15 | "language": com.google.javascript.jscomp.CompilerOptions.LanguageMode.ECMASCRIPT5, 16 | "checkSymbols": true, 17 | "checkTypes": true 18 | }, 19 | "CompilationLevel": "ADVANCED_OPTIMIZATIONS", 20 | "loggingLevel": "FINE", 21 | "externExportsPath": "./externs.js" 22 | }, 23 | "name": "bin/almond", 24 | "include": ["main"], 25 | "stubModules": ["text"], 26 | "wrap": { 27 | "startFile": ["fileoverview.js", "typedef.js", "global-backfills.js", "lib/jscc/io/io.js", "lib/jscc/log/log.js", "lib/jscc/bitset/bitset.js"], 28 | "endFile": ["exports.js", "exports-require.js", "require-rhino-config.js", "require-main.js"] 29 | }, 30 | "out": "./bin/jscc-rhino.js", 31 | "logLevel": 2 32 | }) 33 | -------------------------------------------------------------------------------- /require-rhino-config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * RequireJS configuration for Rhino. 3 | */ 4 | requirejs.config({ 5 | baseUrl: ".", 6 | paths: { 7 | "text": "bin/text", 8 | "has": "volo/has" 9 | }, 10 | map: { 11 | "*": { 12 | "lib/jscc/io/io": "lib/jscc/io/ioRhino", 13 | "lib/jscc/log/log": "lib/jscc/log/logJava", 14 | "lib/jscc/bitset": "lib/jscc/bitset/BitSetJava" 15 | } 16 | }, 17 | nodeRequire: require, 18 | config: { 19 | "lib/jscc/global": { 20 | "version": "0.40.1" 21 | }, 22 | "env": "rhino" 23 | } 24 | }); 25 | -------------------------------------------------------------------------------- /resolvePackageDirectories.js: -------------------------------------------------------------------------------- 1 | (function(root, factory) { 2 | if (typeof define === 'function' && define.amd) { 3 | define(["require", "async", "./asyncSupport"], factory); 4 | } else if (typeof module === 'object' && module.exports) { 5 | module.exports = factory(require); 6 | } else { 7 | root.jsccresolvePackageDirectories = factory(function(mod) { 8 | return root["jscc" + mod]; 9 | }); 10 | } 11 | }(this, function(require) { 12 | require("./asyncSupport"); 13 | var async = require("async"); 14 | 15 | var thisDirName = ""; 16 | if (typeof __dirname === "string") { 17 | thisDirName = __dirname; 18 | } else if (typeof __DIR__ === "string") { 19 | thisDirName = __DIR__; 20 | } 21 | 22 | // Backfill for path.join when running in non-Node environments 23 | function pathJoin() { 24 | var resultQueue = [], index, current; 25 | for (index = 0; index < arguments.length; index++) { 26 | current = arguments[index]; 27 | if (typeof current === "string" && current.trim() !== "") { 28 | resultQueue.push(current.trim().replace(/^[\\\/]*/, "").replace(/[\\\/]*$/, "")); 29 | } 30 | } 31 | if (!/^[A-Za-z]:(?:[\\\/].*)?$/.test(resultQueue[0])) { 32 | resultQueue.unshift(""); 33 | } 34 | return resultQueue.join("/"); 35 | } 36 | 37 | function isDirectory(dirPath, callback) { 38 | if (typeof process === "object" && typeof process.version === "string") { 39 | // Node 40 | require("fs").stat(dirPath, function(e, stat) { 41 | callback(e, !e && stat.isDirectory()); 42 | }); 43 | } else if (typeof Java !== "undefined" && typeof Java.type === "function") { 44 | // Nashorn 45 | var File = Java.type("java.io.File"); 46 | var file = new File(dirPath); 47 | callback(null, file.exists() && file.isDirectory()); 48 | } else if (typeof java !== "undefined") { 49 | // Rhino 50 | var rhinoFile = new java.io.File(dirPath); 51 | callback(null, rhinoFile.exists() && rhinoFile.isDirectory()); 52 | } else { 53 | callback( 54 | new Error("Platform is not Node, Nashorn, or Rhino, so filesystem operations are currently unsupported.")); 55 | } 56 | } 57 | 58 | function resolveDefault(moduleName, callback) { 59 | var mainModulePath = pathJoin(thisDirName, "node_modules", moduleName); 60 | isDirectory(mainModulePath, function(e, result) { 61 | if (!e && result) { 62 | callback(null, mainModulePath); 63 | return; 64 | } 65 | callback(new Error("Could not resolve moduleName '" + moduleName + "'" + (e ? (": " + e.message) : "."))); 66 | }); 67 | } 68 | 69 | function resolveLast(parentDirPath, moduleName, callback) { 70 | if (parentDirPath) { 71 | var childPath = pathJoin(parentDirPath, "node_modules", moduleName); 72 | isDirectory(childPath, function(err, result) { 73 | if (!err && result) { 74 | callback(null, childPath); 75 | return; 76 | } 77 | resolveDefault(moduleName, callback); 78 | }); 79 | } else { 80 | resolveDefault(moduleName, callback); 81 | } 82 | } 83 | 84 | var resolve = async.memoize(function(packageTreeString, callback) { 85 | var match = /^(.*)\s(\S+)$/.exec(packageTreeString.trim()); 86 | if (match) { 87 | resolve(match[1], function(err, parentPath) { 88 | if (err) { 89 | callback(err); 90 | return; 91 | } 92 | resolveLast(parentPath, match[2], callback); 93 | }); 94 | } else { 95 | resolveDefault(packageTreeString.trim(), callback); 96 | } 97 | }, function(packageTreeString) { 98 | return packageTreeString.trim().replace(/\s+/g, " "); 99 | }); 100 | 101 | /** 102 | * To work with npm versions 2 and 3, whose installation behavior differs, 103 | * use this function. Specify each module path as a space-delimited package 104 | * tree. For example, to specify that we want the path to the version of 105 | * the "esprima" package that the "amdclean" package uses, use the path 106 | * "amdclean esprima". 107 | * @param {!(string|Array)} modulePaths - The space-delimited package 108 | * tree or trees, e.g., "amdclean esprima" or ["amdclean esprima", "amdclean escodegen"] 109 | * @param {function(?Error, Array)=} cb - An optional callback that takes a 110 | * nullable Error parameter and a parameter containing an array of paths to each 111 | * module directory 112 | * @returns {(undefined|Array)} If there is no callback, returns an array of 113 | * paths to each module directory 114 | */ 115 | function getNodeModuleDependencyPaths(modulePaths, cb) { 116 | if (typeof modulePaths === "string") { 117 | modulePaths = [modulePaths]; 118 | } 119 | 120 | if (typeof cb === "function") { 121 | async.map(modulePaths, resolve, cb); 122 | return; 123 | } 124 | var outerError, outerResult, done = false; 125 | async.map(modulePaths, resolve, function(error, result) { 126 | outerError = error; 127 | outerResult = result; 128 | done = true; 129 | }); 130 | while (!done) { 131 | // no-op 132 | } 133 | if (outerError) { 134 | throw outerError; 135 | } 136 | return outerResult; 137 | } 138 | 139 | return getNodeModuleDependencyPaths; 140 | })); -------------------------------------------------------------------------------- /samples/99-bottles-of-beer.xpl: -------------------------------------------------------------------------------- 1 | //The wonderful "99 bottles of beer"-program 2 | bottles = 99; 3 | do 4 | { 5 | //The output will not be the prettiest, but that is limited 6 | //by the implementation (you can change it if you want ;)) 7 | write bottles; 8 | 9 | if bottles == 1 say 'bottle of beer on the wall,'; 10 | else say 'bottles of beer on the wall,'; 11 | 12 | write bottles; 13 | if bottles == 1 14 | say 'bottle of beer'; 15 | else 16 | say 'bottles of beer'; 17 | 18 | say 'Take one down, pass it around,'; 19 | bottles = bottles - 1; 20 | 21 | write bottles; 22 | if bottles == 0 say 'no more bottles of beer on the wall'; 23 | else if bottles == 1 say 'bottle of beer on the wall'; 24 | else say 'bottles of beer on the wall'; 25 | 26 | say ''; //Empty line 27 | } 28 | while bottles > 0; 29 | 30 | say 'That''s it!'; -------------------------------------------------------------------------------- /samples/Makefile: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------- 2 | # Makefile for JS/CC Samples 3 | # This Makefile is in the Public Domain. 4 | #------------------------------------------------------------------------------- 5 | 6 | EXEC = calc.exe calc.js calc.html xpl.js xpl_opt.js 7 | 8 | all: $(EXEC) 9 | @echo. 10 | @echo --- Compilation succeeded! --- 11 | 12 | calc.exe: calc_dotnet.par 13 | ..\jscc -o calc.js -t ..\driver.js_ -w calc_dotnet.par 14 | jsc /out:calc.exe /t:exe calc.js 15 | @del calc.js 16 | 17 | calc.js: calc_wsh.par 18 | ..\jscc -o calc.js -t ..\driver.js_ -w calc_wsh.par 19 | 20 | calc.html: calc_web.par 21 | ..\jscc -o calc.html -t ..\driver_web.js_ -w calc_web.par 22 | 23 | xpl.js: xpl.par 24 | ..\jscc -o xpl.js -t ..\driver.js_ -w xpl.par 25 | 26 | xpl_opt.js: xpl_opt.par 27 | ..\jscc -o xpl_opt.js -t ..\driver.js_ -w xpl_opt.par 28 | 29 | clean: 30 | @del $(EXEC) 31 | -------------------------------------------------------------------------------- /samples/calc_dotnet.par: -------------------------------------------------------------------------------- 1 | /~ 2 | Expression calculator written in JS/CC (Microsoft .NET Version) 3 | 4 | This is a WSH-script implementation; For JScript.NET or even JavaScript 5 | on the web, use the according functions to interact with the user. 6 | ~/ 7 | 8 | [* 9 | import System; 10 | 11 | *] 12 | 13 | /~ 14 | --- These are the token definitions --- 15 | ~/ 16 | ! ' |\t' ; /~ Characters to be ignored... ~/ 17 | 18 | '\(' /~ Non-associative tokens ~/ 19 | '\)' 20 | '[0-9]+' INT [* %match = parseInt( %match ); *] 21 | ; 22 | 23 | < '\+' /~ Left-associative tokens, lowest precedence ~/ 24 | '\-'; 25 | 26 | < '\*' /~ Left-associative tokens, highest precedence ~/ 27 | '/'; 28 | 29 | ## 30 | 31 | /~ 32 | --- And here's the grammar specification --- 33 | ~/ 34 | 35 | p: e [* print( %1 ); *] 36 | ; 37 | 38 | /~ 39 | Don't confuse with the tokens: 40 | Here, we use the unescaped values because these are not 41 | interpretered as regular expressions at this position! 42 | ~/ 43 | e: e '+' e [* %% = %1 + %3; *] 44 | | e '-' e [* %% = %1 - %3; *] 45 | | e '*' e [* %% = %1 * %3; *] 46 | | e '/' e [* %% = %1 / %3; *] 47 | | '-' e &'*' [* %% = %2 * -1; *] 48 | | '(' e ')' [* %% = %2; *] 49 | | INT 50 | ; 51 | 52 | /~ 53 | This is the parser entry point; Because this entry point could be 54 | very individual, the compiler programmer has to decide which way 55 | he want to read the source, parse it and report the errors, if 56 | there are any. 57 | ~/ 58 | [* 59 | var error_offsets = new Array(); 60 | var error_lookaheads = new Array(); 61 | var error_count = 0; 62 | 63 | print( "Please enter an expression:" ); 64 | var str = new String( Console.ReadLine() ); 65 | 66 | ##PREFIX##_dbg_withtrace = true; 67 | ##PREFIX##_dbg_withparsetree = true; 68 | ##PREFIX##_dbg_withstepbystep = true; 69 | 70 | if( ( error_count = __##PREFIX##parse( str, 71 | error_offsets, error_lookaheads ) ) > 0 ) 72 | { 73 | for( var i = 0; i < error_count; i++ ) 74 | print( "Parse error near \"" 75 | + str.substr( error_offsets[i] ) + 76 | "\", expecting \"" + 77 | error_lookaheads[i].join() + 78 | "\"" ); 79 | } 80 | *] 81 | -------------------------------------------------------------------------------- /samples/calc_web.par: -------------------------------------------------------------------------------- 1 | /~ 2 | Expression calculator written in JS/CC (browser-based JavaScript Version) 3 | ~/ 4 | 5 | [* 6 | 7 | 8 | 9 | 83 | 84 | 85 | *] 86 | -------------------------------------------------------------------------------- /samples/calc_wsh.par: -------------------------------------------------------------------------------- 1 | /~ 2 | Expression calculator written in JS/CC (Windows Script Host Version) 3 | 4 | This is a WSH-script implementation; For JScript.NET or even JavaScript 5 | on the web, use the according functions to interact with the user. 6 | ~/ 7 | 8 | /~ 9 | --- These are the token definitions --- 10 | ~/ 11 | ! ' |\t' ; /~ Characters to be ignored... ~/ 12 | 13 | '\(' /~ Non-associative tokens ~/ 14 | '\)' 15 | '[0-9]+' INT [* %match = parseInt( %match ); *] 16 | ; 17 | 18 | < '\+' /~ Left-associative tokens, lowest precedence ~/ 19 | '\-'; 20 | 21 | < '\*' /~ Left-associative tokens, highest precedence ~/ 22 | '/'; 23 | 24 | ## 25 | 26 | /~ 27 | --- And here's the grammar specification --- 28 | ~/ 29 | 30 | p: e [* WScript.Echo( %1 ); *] 31 | ; 32 | 33 | /~ 34 | Don't confuse with the tokens: 35 | Here, we use the unescaped values because these are not 36 | interpretered as regular expressions at this position! 37 | ~/ 38 | e: e '+' e [* %% = %1 + %3; *] 39 | | e '-' e [* %% = %1 - %3; *] 40 | | e '*' e [* %% = %1 * %3; *] 41 | | e '/' e [* %% = %1 / %3; *] 42 | | '-' e &'*' [* %% = %2 * -1; *] 43 | | '(' e ')' [* %% = %2; *] 44 | | INT 45 | ; 46 | 47 | /~ 48 | This is the parser entry point; Because this entry point could be 49 | very individual, the compiler programmer has to decide which way 50 | he want to read the source, parse it and report the errors, if 51 | there are any. 52 | ~/ 53 | [* 54 | var error_offsets = new Array(); 55 | var error_lookaheads = new Array(); 56 | var error_count = 0; 57 | 58 | WScript.Echo( "Please enter an expression:" ); 59 | var str = new String( WScript.StdIn.ReadLine() ); 60 | 61 | //##PREFIX##_dbg_withtrace = true; 62 | ##PREFIX##_dbg_withparsetree = true; 63 | //##PREFIX##_dbg_withstepbystep = true; 64 | 65 | if( ( error_count = __##PREFIX##parse( str, 66 | error_offsets, error_lookaheads ) ) > 0 ) 67 | { 68 | for( var i = 0; i < error_count; i++ ) 69 | WScript.Echo( "Parse error near \"" 70 | + str.substr( error_offsets[i] ) + 71 | "\", expecting \"" + 72 | error_lookaheads[i].join() + 73 | "\"" ); 74 | } 75 | *] 76 | -------------------------------------------------------------------------------- /samples/countdown.xpl: -------------------------------------------------------------------------------- 1 | //A rocketry launch countdown ;) 2 | say '--- The final countdown progam ---'; 3 | 4 | do 5 | { 6 | say 'Enter your starting number (it must be greater or equal 10!):'; 7 | read count; 8 | 9 | if count < 10 say 'The number is lower 10!'; 10 | } 11 | while count < 10; 12 | 13 | say 'Starting sequence...'; 14 | while count >= 0 do 15 | { 16 | write count; 17 | 18 | //Ignition at 3 loops before lift-off... 19 | if count == 3 say 'Ignition...'; 20 | else if count == 0 say '...and lift-off!'; 21 | count = count - 1; 22 | } -------------------------------------------------------------------------------- /samples/hello.xpl: -------------------------------------------------------------------------------- 1 | //This is a simple Hello World script, written in XPL. 2 | say 'Hello World'; -------------------------------------------------------------------------------- /test/jscc/integrity.Test.js: -------------------------------------------------------------------------------- 1 | suite("integrity", function() { 2 | var path = require('path'); 3 | if (typeof requirejs === 'undefined') { 4 | requirejs = require('requirejs'); 5 | requirejs.config({ 6 | baseUrl: path.join(__dirname, '../../lib/jscc'), 7 | nodeRequire: require, 8 | packages: [ 9 | { 10 | name: "squirejs", 11 | location: "../../node_modules/squirejs", 12 | main: "src/Squire" 13 | } 14 | ], 15 | paths: { 16 | "jscc": "main", 17 | "sinon": "../../node_modules/sinon/pkg/sinon", 18 | "text": "../../node_modules/requirejs-text/text", 19 | "has": "../../volo/has" 20 | }, 21 | map: { 22 | "*": { 23 | "bitset": "bitset/BitSet32", 24 | "io/io": "io/ioNode", 25 | "log/log": "log/logNode" 26 | } 27 | } 28 | }); 29 | } 30 | 31 | var sinon = requirejs('sinon'); 32 | var chai = requirejs('chai'); 33 | var Squire = requirejs('squirejs'); 34 | 35 | sinon.assert.expose(chai.assert, { prefix: "" }); 36 | var assert = chai.assert; 37 | var injector = new Squire(); 38 | 39 | var sandbox; 40 | setup("setup", function() { 41 | injector.configure(); 42 | sandbox = sinon.sandbox.create(); 43 | var logStub = sandbox.stub({ 44 | fatal: function(msg) { 45 | }, 46 | error: function(msg) { 47 | }, 48 | warn: function(msg) { 49 | }, 50 | info: function(msg) { 51 | }, 52 | debug: function(msg) { 53 | }, 54 | trace: function(msg) { 55 | }, 56 | setLevel: function(msg) { 57 | } 58 | }); 59 | injector.mock("log/log", logStub); 60 | injector.mock("log/logNode", logStub); 61 | injector.store(["log/log", "log/logNode", "global", "integrity"]); 62 | }); 63 | 64 | teardown("teardown", function() { 65 | injector.remove(); 66 | sandbox.restore(); 67 | requirejs.undef("log/log"); 68 | requirejs.undef("log/logNode"); 69 | requirejs.undef("global"); 70 | requirejs.undef("integrity"); 71 | }); 72 | 73 | [ 74 | { symbolTypes: [0, 3, 1, 2], errorCount: 1 }, 75 | { symbolTypes: [0, 2, 1], errorCount: 0 }, 76 | { symbolTypes: [0, 3, 1, 3], errorCount: 2 }, 77 | { symbolTypes: [], errorCount: 0 } 78 | ].forEach(function(item) { 79 | test("integrity.undef logs " + item.errorCount + " error" + (item.errorCount == 1 ? "" : "s") + 80 | " with " + item.symbolTypes.length + " symbol" + (item.symbolTypes.length == 1 ? "" : "s") + 81 | " and " + item.errorCount + " undefined terminal" + (item.errorCount == 1 ? "" : "s"), 82 | injector.run(["mocks", "integrity", "classes/Symbol", "enums/SYM"], 83 | function(mocks, integrity, Symbol, SYM) { 84 | var global = mocks.store["global"]; 85 | var log = mocks.store["log/logNode"]; 86 | log.error.resetHistory(); 87 | var term = new Symbol({ kind: SYM.TERM, defined: false }); 88 | var defined = new Symbol({ kind: SYM.NONTERM, defined: true }); 89 | var definedTerm = new Symbol({ kind: SYM.TERM, defined: true }); 90 | var undefined = new Symbol({ kind: SYM.NONTERM, defined: false }); 91 | var symbols = [term, defined, definedTerm, undefined]; 92 | item.symbolTypes.forEach(function(index) { 93 | global.symbols.push(symbols[index]); 94 | }); 95 | 96 | integrity.undef(); 97 | 98 | assert.callCount(log.error, item.errorCount); 99 | })); 100 | }); 101 | }); -------------------------------------------------------------------------------- /test/jscc/parse.Test.js: -------------------------------------------------------------------------------- 1 | suite("parse", function() { 2 | var path = require('path'); 3 | if (typeof requirejs === 'undefined') { 4 | requirejs = require('requirejs'); 5 | requirejs.config({ 6 | baseUrl: path.join(__dirname, '../../lib/jscc'), 7 | nodeRequire: require, 8 | packages: [ 9 | { 10 | name: "squirejs", 11 | location: "../node_modules/squirejs", 12 | main: "src/Squire" 13 | } 14 | ], 15 | paths: { 16 | "jscc": "main", 17 | "sinon": "../../node_modules/sinon/pkg/sinon", 18 | "text": "../../node_modules/requirejs-text/text", 19 | "has": "../../volo/has" 20 | }, 21 | map: { 22 | "*": { 23 | "bitset": "bitset/BitSet32", 24 | "io/io": "io/ioNode", 25 | "log/log": "log/logNode" 26 | } 27 | } 28 | }); 29 | } 30 | 31 | var sinon = requirejs('sinon'); 32 | var chai = requirejs('chai'); 33 | var Squire = requirejs('squirejs'); 34 | 35 | sinon.assert.expose(chai.assert, { prefix: "" }); 36 | var assert = chai.assert; 37 | var injector = new Squire(); 38 | 39 | var sandbox; 40 | setup("setup", function() { 41 | injector.configure(); 42 | sandbox = sinon.sandbox.create(); 43 | var logStub = sandbox.stub({ 44 | fatal: function(msg) { 45 | }, 46 | error: function(msg) { 47 | }, 48 | warn: function(msg) { 49 | }, 50 | info: function(msg) { 51 | }, 52 | debug: function(msg) { 53 | }, 54 | trace: function(msg) { 55 | }, 56 | setLevel: function(level) { 57 | } 58 | }); 59 | injector.mock("log/log", logStub); 60 | injector.mock("log/logNode", logStub); 61 | injector.mock("io/io", requirejs("io/ioNode")); 62 | injector.store(["log/log", "log/logNode", "global", "util"]); 63 | }); 64 | 65 | teardown("teardown", function() { 66 | injector.remove(); 67 | sandbox.restore(); 68 | }); 69 | 70 | [ 71 | { semi: ";", description: "a semicolon" }, 72 | { semi: "", description: "no semicolon" }, 73 | { semi: " ;", description: "a semicolon preceded by a space" }, 74 | { semi: "\n ;", description: "a semicolon preceded by a newline and a space" }, 75 | { semi: "; /~ Comment ~/", description: "a semicolon followed by a comment" } 76 | ].forEach(function(item) { 77 | test("Permits " + item.description + " after whitespace terminal definition", 78 | injector.run(["mocks", "parse", "enums/EXEC"], function(mocks, parse) { 79 | var log = mocks.store["log/logNode"]; 80 | log.fatal.resetHistory(); 81 | log.error.resetHistory(); 82 | 83 | var global = mocks.store["global"]; 84 | 85 | var source = "! ' '" + item.semi + "\n" + 86 | "##\n" + 87 | "p: e [* alert( %1 ); *]\n" + 88 | " ;\n" + 89 | "e: ;\n"; 90 | 91 | parse(source, ""); 92 | 93 | assert.notCalled(log.fatal); 94 | assert.notCalled(log.error); 95 | })); 96 | }); 97 | }); -------------------------------------------------------------------------------- /test/jscc/printtab.Test.js: -------------------------------------------------------------------------------- 1 | suite("printtab", function() { 2 | var path = require('path'); 3 | if (typeof requirejs === 'undefined') { 4 | requirejs = require('requirejs'); 5 | requirejs.config({ 6 | baseUrl: path.join(__dirname, '../../lib/jscc'), 7 | nodeRequire: require, 8 | packages: [ 9 | { 10 | name: "squirejs", 11 | location: "../node_modules/squirejs", 12 | main: "src/Squire" 13 | } 14 | ], 15 | paths: { 16 | "jscc": "main", 17 | "sinon": "../../node_modules/sinon/pkg/sinon", 18 | "text": "../../node_modules/requirejs-text/text", 19 | "has": "../../volo/has" 20 | }, 21 | map: { 22 | "*": { 23 | "bitset": "bitset/BitSet32", 24 | "log/log": "log/logNode", 25 | "io/io": "io/ioNode" 26 | } 27 | } 28 | }); 29 | } 30 | 31 | var sinon = requirejs('sinon'); 32 | var chai = requirejs('chai'); 33 | var Squire = requirejs('squirejs'); 34 | 35 | sinon.assert.expose(chai.assert, { prefix: "" }); 36 | var assert = chai.assert; 37 | var injector = new Squire(); 38 | 39 | var sandbox; 40 | setup("setup", function() { 41 | injector.configure(); 42 | sandbox = sinon.sandbox.create(); 43 | var logStub = sandbox.stub({ 44 | fatal: function(msg) { 45 | }, 46 | error: function(msg) { 47 | }, 48 | warn: function(msg) { 49 | }, 50 | info: function(msg) { 51 | }, 52 | debug: function(msg) { 53 | }, 54 | trace: function(msg) { 55 | }, 56 | setLevel: function(level) { 57 | } 58 | }); 59 | var ioStub = sandbox.stub({ 60 | read_all_input: function(options) { 61 | }, 62 | read_template: function(options) { 63 | }, 64 | write_output: function(options) { 65 | } 66 | }); 67 | injector.mock("log/log", logStub); 68 | injector.mock("log/logNode", logStub); 69 | injector.mock("io/io", ioStub); 70 | injector.mock("io/ioNode", ioStub); 71 | injector.store(["global", "log/log", "log/logNode"]); 72 | }); 73 | 74 | teardown("teardown", function() { 75 | injector.remove(); 76 | sandbox.restore(); 77 | }); 78 | 79 | test("print_actions logs an error if a %n wildcard does not match the right-hand side of a production", 80 | injector.run(["mocks", "printtab", "classes/Production", "classes/Symbol"], 81 | function(mocks, printtab, Production, Symbol) { 82 | var global = mocks.store["global"]; 83 | var log = mocks.store["log/logNode"]; 84 | global.productions = []; 85 | global.symbols = []; 86 | global.productions.push(new Production({ 87 | id: 0, 88 | code: "return %1;", 89 | lhs: 0, 90 | rhs: [] 91 | })); 92 | global.symbols.push(new Symbol({ 93 | id: 0, 94 | label: "testLabel" 95 | })); 96 | log.error.resetHistory(); 97 | printtab.print_actions(); 98 | assert.called(log.error); 99 | })); 100 | }); -------------------------------------------------------------------------------- /test/jscc/regex.Test.js: -------------------------------------------------------------------------------- 1 | suite("regex", function() { 2 | var path = require('path'); 3 | if (typeof requirejs === 'undefined') { 4 | requirejs = require('requirejs'); 5 | requirejs.config({ 6 | baseUrl: path.join(__dirname, '../../lib/jscc'), 7 | nodeRequire: require, 8 | packages: [ 9 | { 10 | name: "squirejs", 11 | location: "../../node_modules/squirejs", 12 | main: "src/Squire" 13 | } 14 | ], 15 | paths: { 16 | "sinon": "../../node_modules/sinon/pkg/sinon", 17 | "text": "../../node_modules/requirejs-text/text", 18 | "has": "../../volo/has" 19 | }, 20 | map: { 21 | "*": { 22 | "log/log": "log/logNode", 23 | "io/io": "io/ioNode", 24 | "bitset": "bitset/BitSet32" 25 | } 26 | } 27 | }); 28 | } 29 | 30 | var sinon = requirejs('sinon'); 31 | var chai = requirejs('chai'); 32 | var Squire = requirejs('squirejs'); 33 | 34 | sinon.assert.expose(chai.assert, { prefix: "" }); 35 | var assert = chai.assert; 36 | var injector = new Squire(); 37 | 38 | var sandbox; 39 | setup("setup", function() { 40 | injector.configure(); 41 | sandbox = sinon.sandbox.create(); 42 | var logStub = sandbox.stub({ 43 | fatal: function(msg) { 44 | }, 45 | error: function(msg) { 46 | }, 47 | warn: function(msg) { 48 | }, 49 | info: function(msg) { 50 | }, 51 | debug: function(msg) { 52 | }, 53 | trace: function(msg) { 54 | }, 55 | setLevel: function(level) { 56 | } 57 | }); 58 | var ioStub = sandbox.stub({ 59 | read_all_input: function(options) { 60 | }, 61 | read_template: function(options) { 62 | }, 63 | write_output: function(options) { 64 | } 65 | }); 66 | injector.mock("log/log", logStub); 67 | injector.mock("log/logNode", logStub); 68 | injector.mock("io/io", ioStub); 69 | injector.mock("io/ioNode", ioStub); 70 | injector.store(["global", "log/log", "log/logNode"]); 71 | }); 72 | 73 | teardown("teardown", function() { 74 | injector.remove(); 75 | sandbox.restore(); 76 | }); 77 | 78 | [ 79 | { pattern: "[A-Z][A-Z0-9]*", valid: true }, 80 | { pattern: "ab|c", valid: true }, 81 | { pattern: "[0-9]+", valid: true }, 82 | { pattern: "[A-Z", valid: false }, 83 | { pattern: "*", valid: false }, 84 | { pattern: "\\*", valid: true }, 85 | { pattern: "[", valid: false }, 86 | { pattern: "\\[", valid: true }, 87 | { pattern: "]", valid: false }, 88 | { pattern: "\\]", valid: true }, 89 | { pattern: "(", valid: false }, 90 | { pattern: "\\(", valid: true }, 91 | { pattern: ")", valid: false }, 92 | { pattern: "\\)", valid: true }, 93 | { pattern: "|", valid: false }, 94 | { pattern: "\\|", valid: true }, 95 | { pattern: "?", valid: false }, 96 | { pattern: "\\?", valid: true }, 97 | // Backslash at end of pattern translates as literal backslash; 98 | // a little messy, but probably not worth changing 99 | { pattern: "\\", valid: true }, 100 | { pattern: "\\\\", valid: true }, 101 | { pattern: ".", valid: true }, 102 | { pattern: "\\.", valid: true }, 103 | { pattern: "\\220", valid: true } 104 | ].forEach(function(item) { 105 | test("Regex '" + item.pattern + "' " + (item.valid ? "does not log" : "logs") + " an error", 106 | injector.run(["mocks", "regex"], 107 | function(mocks, regex) { 108 | var log = mocks.store["log/logNode"]; 109 | log.error.resetHistory(); 110 | regex(item.pattern, 0, false); 111 | if (item.valid) { 112 | assert.notCalled(log.error); 113 | } else { 114 | assert.called(log.error); 115 | } 116 | })); 117 | }); 118 | 119 | }); -------------------------------------------------------------------------------- /test/jscc/tabgen.Test.js: -------------------------------------------------------------------------------- 1 | suite("tabgen", function() { 2 | var path = require('path'); 3 | if (typeof requirejs === 'undefined') { 4 | requirejs = require('requirejs'); 5 | requirejs.config({ 6 | baseUrl: path.join(__dirname, '../../lib/jscc'), 7 | nodeRequire: require, 8 | packages: [ 9 | { 10 | name: "squirejs", 11 | location: "../node_modules/squirejs", 12 | main: "src/Squire" 13 | } 14 | ], 15 | paths: { 16 | "jscc": "main", 17 | "sinon": "../../node_modules/sinon/pkg/sinon", 18 | "text": "../../node_modules/requirejs-text/text", 19 | "has": "../../volo/has" 20 | }, 21 | map: { 22 | "*": { 23 | "log/log": "log/logNode", 24 | "io/io": "io/ioNode", 25 | "bitset": "bitset/BitSet32" 26 | } 27 | } 28 | }); 29 | } 30 | 31 | var sinon = requirejs('sinon'); 32 | var chai = requirejs('chai'); 33 | var Squire = requirejs('squirejs'); 34 | 35 | sinon.assert.expose(chai.assert, { prefix: "" }); 36 | var assert = chai.assert; 37 | var injector = new Squire(); 38 | 39 | var sandbox; 40 | setup("setup", function() { 41 | injector.configure(); 42 | sandbox = sinon.sandbox.create(); 43 | var logStub = sandbox.stub({ 44 | fatal: function(msg) { 45 | }, 46 | error: function(msg) { 47 | }, 48 | warn: function(msg) { 49 | }, 50 | info: function(msg) { 51 | }, 52 | debug: function(msg) { 53 | }, 54 | trace: function(msg) { 55 | }, 56 | setLevel: function(level) { 57 | } 58 | }); 59 | var ioStub = sandbox.stub({ 60 | read_all_input: function(options) { 61 | }, 62 | read_template: function(options) { 63 | }, 64 | write_output: function(options) { 65 | } 66 | }); 67 | injector.mock("log/log", logStub); 68 | injector.mock("log/logNode", logStub); 69 | injector.mock("io/io", ioStub); 70 | injector.mock("io/ioNode", ioStub); 71 | injector.store(["global"]); 72 | }); 73 | 74 | teardown("teardown", function() { 75 | injector.remove(); 76 | sandbox.restore(); 77 | }); 78 | 79 | [ 80 | { label: "someLabel", terminating: true, special: "NONE", expected: -1, overrides: [] }, 81 | { 82 | label: "someLabel", terminating: false, special: "NONE", expected: 0, overrides: [ 83 | { label: "someLabel", terminating: false, special: "NONE" } 84 | ] 85 | }, 86 | { 87 | label: "SomeLabel", terminating: false, special: "NONE", expected: -1, overrides: [ 88 | { label: "someLabel", terminating: false, special: "NONE" } 89 | ] 90 | }, 91 | { 92 | label: "someLabel", terminating: true, special: "EOF", expected: 2, overrides: [ 93 | { label: "someLabel", terminating: false, special: "EOF" }, 94 | { label: "someLabel", terminating: true, special: "WHITESPACE" }, 95 | { label: "someLabel", terminating: true, special: "EOF" } 96 | ] 97 | } 98 | ].forEach(function(item) { 99 | test("Calling find_symbol with label '" + item.label + "', kind 'SYM." + 100 | (item.terminating ? "TERM" : "NONTERM") + "', and special '" + 101 | (typeof item.special === 'undefined' ? "undefined" : item.special) + "' returns " + 102 | item.expected, 103 | injector.run(["mocks", "tabgen", "enums/SYM", "enums/SPECIAL", 104 | "classes/Symbol"], function(mocks, tabgen, SYM, SPECIAL, Symbol) { 105 | var global = mocks.store["global"]; 106 | // Remove default symbols now added by the jscc.global constructor 107 | global.symbols = []; 108 | item.overrides.forEach(function(override) { 109 | if (typeof override.terminating === 'boolean') { 110 | override.kind = override.terminating ? SYM.TERM : SYM.NONTERM; 111 | delete override.terminating; 112 | } 113 | if (typeof override.special === 'string') { 114 | var newSpecial = SPECIAL.NONE; 115 | switch (override.special) { 116 | case "EOF": 117 | newSpecial = SPECIAL.EOF; 118 | break; 119 | case "ERROR": 120 | newSpecial = SPECIAL.ERROR; 121 | break; 122 | case "WHITESPACE": 123 | newSpecial = SPECIAL.WHITESPACE; 124 | break; 125 | default: 126 | break; 127 | } 128 | override.special = newSpecial; 129 | } 130 | global.symbols.push(new Symbol(override)); 131 | }); 132 | var kind = item.terminating ? SYM.TERM : SYM.NONTERM; 133 | var special; 134 | switch (item.special) { 135 | case "NONE": 136 | special = SPECIAL.NONE; 137 | break; 138 | case "EOF": 139 | special = SPECIAL.EOF; 140 | break; 141 | case "ERROR": 142 | special = SPECIAL.ERROR; 143 | break; 144 | case "WHITESPACE": 145 | special = SPECIAL.WHITESPACE; 146 | break; 147 | default: 148 | break; 149 | } 150 | var result = tabgen.find_symbol(item.label, kind, special); 151 | assert.strictEqual(result, item.expected); 152 | })); 153 | }); 154 | }); -------------------------------------------------------------------------------- /test/jscc/util.Test.js: -------------------------------------------------------------------------------- 1 | suite("util", function() { 2 | var path = require('path'); 3 | if (typeof requirejs === 'undefined') { 4 | requirejs = require('requirejs'); 5 | requirejs.config({ 6 | baseUrl: path.join(__dirname, '../../lib/jscc'), 7 | nodeRequire: require, 8 | packages: [ 9 | { 10 | name: "squirejs", 11 | location: "../../node_modules/squirejs", 12 | main: "src/Squire" 13 | } 14 | ], 15 | paths: { 16 | "jscc": "main", 17 | "sinon": "../../node_modules/sinon/pkg/sinon", 18 | "text": "../../node_modules/requirejs-text/text", 19 | "has": "../../volo/has" 20 | }, 21 | map: { 22 | "*": { 23 | "io/io": "io/ioNode", 24 | "log/log": "log/logNode", 25 | "bitset": "bitset/BitSet32" 26 | } 27 | } 28 | }); 29 | } 30 | 31 | var sinon = requirejs('sinon'); 32 | var chai = requirejs('chai'); 33 | var Squire = requirejs('squirejs'); 34 | 35 | sinon.assert.expose(chai.assert, { prefix: "" }); 36 | var assert = chai.assert; 37 | var injector = new Squire(); 38 | 39 | var sandbox; 40 | setup("setup", function() { 41 | injector.configure(); 42 | sandbox = sinon.sandbox.create(); 43 | var logStub = sandbox.stub({ 44 | fatal: function(msg) { 45 | }, 46 | error: function(msg) { 47 | }, 48 | warn: function(msg) { 49 | }, 50 | info: function(msg) { 51 | }, 52 | debug: function(msg) { 53 | }, 54 | trace: function(msg) { 55 | }, 56 | setLevel: function(level) { 57 | } 58 | }); 59 | var ioStub = sandbox.stub({ 60 | read_all_input: function(options) { 61 | }, 62 | read_template: function(options) { 63 | }, 64 | write_output: function(options) { 65 | } 66 | }); 67 | injector.mock("log/log", logStub); 68 | injector.mock("log/logNode", logStub); 69 | injector.mock("io/io", ioStub); 70 | injector.mock("io/ioNode", ioStub); 71 | }); 72 | 73 | teardown("teardown", function() { 74 | injector.remove(); 75 | sandbox.restore(); 76 | }); 77 | 78 | [ 79 | { dest: [1, 5, 8], src: [2, 5], result: [1, 2, 5, 8] }, 80 | { dest: [1, 2, 3], src: [], result: [1, 2, 3] }, 81 | { dest: [], src: [1, 2, 3], result: [1, 2, 3] }, 82 | { dest: [0, 1, 2, 3], src: [0.5, 1.5, 2.5, 3.5], result: [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5] } 83 | ].forEach(function(item) { 84 | test("Union of dest_array [" + item.dest.join(", ") + "] and src_array [" + item.src.join(", ") + 85 | "] produces result [" + item.result.join(", ") + "] in any order", 86 | injector.run(["mocks", "util"], function(mocks, util) { 87 | var result = util.union(item.dest, item.src); 88 | assert.sameMembers(result, item.result); 89 | })); 90 | }); 91 | 92 | test("Union does not affect its src_array parameter", injector.run(["mocks", "util"], function(mocks, util) { 93 | var src = [1, 2, 3]; 94 | var dest = [4, 5, 6]; 95 | var result = util.union(dest, src); 96 | assert.deepEqual(src, [1, 2, 3]); 97 | })); 98 | 99 | test("Union modifies dest_array and returns it as the result", 100 | injector.run(["mocks", "util"], function(mocks, util) { 101 | var src = [1, 2, 3]; 102 | var dest = [4, 5, 6]; 103 | var result = util.union(dest, src); 104 | assert.deepEqual(dest, result); 105 | assert.sameMembers(dest, [1, 2, 3, 4, 5, 6]); 106 | })); 107 | }); -------------------------------------------------------------------------------- /test/runners.Test.js: -------------------------------------------------------------------------------- 1 | suite("runners", function() { 2 | var path = require('path'); 3 | var child_process = require('child_process'); 4 | var os = require('os'); 5 | var temp = require('temp').track(); 6 | 7 | if (typeof requirejs === 'undefined') { 8 | requirejs = require('requirejs'); 9 | requirejs.config({ 10 | baseUrl: path.join(__dirname, '../lib/jscc'), 11 | nodeRequire: require, 12 | packages: [ 13 | { 14 | name: "squirejs", 15 | location: "../../node_modules/squirejs", 16 | main: "src/Squire" 17 | } 18 | ], 19 | paths: { 20 | "sinon": "../../node_modules/sinon/pkg/sinon", 21 | "text": "../../node_modules/requirejs-text/text" 22 | } 23 | }); 24 | } 25 | 26 | var chai = requirejs('chai'); 27 | var assert = chai.assert; 28 | var tempDir; 29 | setup("setup", function() { 30 | tempDir = temp.mkdirSync(); 31 | }); 32 | 33 | teardown("teardown", function() { 34 | temp.cleanupSync(); 35 | }); 36 | 37 | [ 38 | "browser", 39 | "nashorn", 40 | "node", 41 | "rhino" 42 | ].forEach(function(platformName) { 43 | test("Runner for " + platformName + " executes without errors", 44 | function(done) { 45 | this.timeout(40000); 46 | var outFilePath = path.join(tempDir, "output-" + platformName + ".js"); 47 | var srcFilePath = path.join(__dirname, "../samples/xpl.par"); 48 | var runnerPath = path.join(__dirname, "../bin", 49 | "jscc-" + platformName + (os.platform() === "win32" ? ".bat" : ".sh")); 50 | var command = "\"" + runnerPath + "\" --src_file \"" + srcFilePath + "\" --out_file \"" + outFilePath + 51 | "\" --logLevel INFO"; 52 | child_process.exec(command, { timeout: 38000 }, function(error, stdout, stderr) { 53 | if (error) { 54 | console.error(error.message); 55 | } 56 | if (stdout) { 57 | console.log("Standard output:"); 58 | console.log(stdout); 59 | } 60 | if (stderr) { 61 | console.log("Standard error:"); 62 | console.log(stderr); 63 | } 64 | done(error); 65 | }); /*.on("exit", function(code, signal) { 66 | assert.isTrue(code === null || code === 0, "There was a non-zero exit code"); 67 | assert.isNull(signal); 68 | done(); 69 | }); */ 70 | }); 71 | 72 | test("Runner for " + platformName + " has a non-zero exit code when there is an error", 73 | function(done) { 74 | this.timeout(40000); 75 | try { 76 | var outFilePath = path.join(tempDir, "output-" + platformName + ".js"); 77 | var srcFilePath = path.join(__dirname, "../samples/xpl.par.invalid"); 78 | var runnerPath = path.join(__dirname, "../bin", 79 | "jscc-" + platformName + (os.platform() === "win32" ? ".bat" : ".sh")); 80 | var command = "\"" + runnerPath + "\" --src_file \"" + srcFilePath + "\" --out_file \"" + outFilePath + 81 | "\" --logLevel INFO"; 82 | child_process.exec(command, { timeout: 38000, stdio: "inherit" }).on("exit", function(code, signal) { 83 | try { 84 | assert.isNull(signal); 85 | assert.isNumber(code); 86 | assert.notStrictEqual(code, 0); 87 | } catch (e) { 88 | done(e); 89 | return; 90 | } 91 | done(); 92 | }); 93 | } catch (e) { 94 | done(e); 95 | } 96 | }); 97 | }); 98 | }); 99 | -------------------------------------------------------------------------------- /test/samples.Test.js: -------------------------------------------------------------------------------- 1 | suite("samples", function() { 2 | var path = require('path'); 3 | if (typeof requirejs === 'undefined') { 4 | requirejs = require('requirejs'); 5 | requirejs.config({ 6 | baseUrl: path.join(__dirname, '../lib/jscc'), 7 | nodeRequire: require, 8 | packages: [ 9 | { 10 | name: "squirejs", 11 | location: "../../node_modules/squirejs", 12 | main: "src/Squire" 13 | } 14 | ], 15 | paths: { 16 | "jscc": "main", 17 | "sinon": "../../node_modules/sinon/pkg/sinon", 18 | "text": "../../node_modules/requirejs-text/text", 19 | "has": "../../volo/has" 20 | }, 21 | map: { 22 | "*": { 23 | "log/log": "log/logNode", 24 | "io/io": "io/ioNode", 25 | "bitset": "bitset/BitSet32" 26 | } 27 | } 28 | }); 29 | } 30 | 31 | var sinon = requirejs('sinon'); 32 | var chai = requirejs('chai'); 33 | var Squire = requirejs('squirejs'); 34 | var temp = requirejs('temp').track(); 35 | 36 | sinon.assert.expose(chai.assert, { prefix: "" }); 37 | var assert = chai.assert; 38 | var injector = new Squire(); 39 | 40 | var sandbox, tempDir; 41 | setup("setup", function() { 42 | injector.configure(); 43 | sandbox = sinon.sandbox.create(); 44 | injector.store(["log/log", "log/logNode"]); 45 | tempDir = temp.mkdirSync(); 46 | 47 | }); 48 | 49 | teardown("teardown", function() { 50 | temp.cleanupSync(); 51 | injector.remove(); 52 | sandbox.restore(); 53 | }); 54 | 55 | [ 56 | "../samples/calc_web.par", 57 | "../samples/xpl.par", 58 | "../samples/xpl_opt.par" 59 | ].forEach(function(inputPath) { 60 | test("Parses sample file '" + inputPath + "' without errors", 61 | injector.run(["mocks", "jscc"], function(mocks, jscc) { 62 | var log = mocks.store["log/logNode"]; 63 | var fatalSpy = sandbox.spy(log, "fatal"); 64 | var errorSpy = sandbox.spy(log, "error"); 65 | var output = ""; 66 | jscc({ 67 | src_file: path.join(__dirname, inputPath), 68 | tpl_file: path.join(__dirname, "../lib/jscc/template/parser-driver-js.txt"), 69 | outputCallback: function(text) { 70 | output = text; 71 | } 72 | }); 73 | assert.notStrictEqual(output, ""); 74 | assert.notCalled(fatalSpy); 75 | assert.notCalled(errorSpy); 76 | })); 77 | }); 78 | 79 | [ 80 | "../samples/99-bottles-of-beer.xpl", 81 | "../samples/countdown.xpl", 82 | "../samples/hello.xpl" 83 | ].forEach(function(inputPath) { 84 | test("Parser generated from xpl.par parses '" + inputPath + "' without errors", 85 | injector.run(["mocks", "jscc"], function(mocks, jscc) { 86 | jscc({ 87 | src_file: path.join(__dirname, "../samples/xpl.par"), 88 | tpl_file: path.join(__dirname, "../lib/jscc/template/parser-driver-js.txt"), 89 | out_file: path.join(tempDir, "xpl.js") 90 | }); 91 | var req = requirejs.config({ 92 | context: "Parser generated from... " + inputPath, 93 | baseUrl: path.join(__dirname, "../lib/jscc"), 94 | paths: { 95 | "text": "../../node_modules/requirejs-text/text", 96 | "xpl": path.join(tempDir, "xpl") 97 | }, 98 | map: { 99 | "*": { 100 | "io/io": "io/ioNode", 101 | "log/log": "log/logNode" 102 | } 103 | } 104 | }); 105 | assert.doesNotThrow(function() { 106 | req(["require", "xpl"], function(require, xpl) { 107 | xpl(inputPath); 108 | }); 109 | }, Error); 110 | })); 111 | }); 112 | }); -------------------------------------------------------------------------------- /webenv/img/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abrobston/jscc/3e3043a7519b00dc9aebfc8f5850cca9237b97ec/webenv/img/back.png -------------------------------------------------------------------------------- /webenv/img/e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abrobston/jscc/3e3043a7519b00dc9aebfc8f5850cca9237b97ec/webenv/img/e.png -------------------------------------------------------------------------------- /webenv/img/l.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abrobston/jscc/3e3043a7519b00dc9aebfc8f5850cca9237b97ec/webenv/img/l.png -------------------------------------------------------------------------------- /webenv/img/la.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abrobston/jscc/3e3043a7519b00dc9aebfc8f5850cca9237b97ec/webenv/img/la.png -------------------------------------------------------------------------------- /webenv/img/ll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abrobston/jscc/3e3043a7519b00dc9aebfc8f5850cca9237b97ec/webenv/img/ll.png -------------------------------------------------------------------------------- /webenv/img/n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abrobston/jscc/3e3043a7519b00dc9aebfc8f5850cca9237b97ec/webenv/img/n.png -------------------------------------------------------------------------------- /webenv/img/rn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abrobston/jscc/3e3043a7519b00dc9aebfc8f5850cca9237b97ec/webenv/img/rn.png -------------------------------------------------------------------------------- /webenv/img/t.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abrobston/jscc/3e3043a7519b00dc9aebfc8f5850cca9237b97ec/webenv/img/t.png -------------------------------------------------------------------------------- /webenv/img/zoom.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abrobston/jscc/3e3043a7519b00dc9aebfc8f5850cca9237b97ec/webenv/img/zoom.gif -------------------------------------------------------------------------------- /webenv/jscc.css: -------------------------------------------------------------------------------- 1 | a:link, a:visited { border:0; text-decoration: none; color: #003168; font-weight: bold; font-size: 10px; } 2 | a:hover { border:0; text-decoration: none; color: #0683FF; font-weight: bold; } 3 | img { border:0; } 4 | 5 | html, body, td { font-family: Courier New, Sans-serif; font-size: 11px; } 6 | table.debug, 7 | table.print { width: 100%; border: 1px solid #707070 ; margin-bottom: 5px; } 8 | table.print td { text-align: center; white-space: nowrap; } 9 | 10 | hr { line-height: 1px; color: black; } 11 | #output, #js_code, 12 | #parsetree { height: 200px; border-top: 1px solid #707070 ; 13 | border-left: 1px solid #707070 ; padding: 10px; overflow: scroll; } 14 | #js_code { height: 300px; } 15 | .elem_title { text-align: center; font-size: 11px; font-weight: bold; 16 | color: white; height: 15px; 17 | background-image: url( "img/back.png" ); 18 | background-repeat: repeat-x; } 19 | 20 | #progname { font-size: 18px; font-weight: bold; margin: 0; padding: 0; text-align: center; } 21 | #version { font-size: 14px; font-weight: bold; margin: 0; padding: 0; text-align: center; } 22 | #copyright { font-size: 12px; font-weight: bold; margin: 0; padding: 0; text-align: center; } 23 | #visit_us { font-size: 12px; color: #bdbdbd; margin: 0; padding: 0; text-align: center; } 24 | #copyrightinfo { border: 3px solid black; font-family: Verdana, Helvetica, Arial, Sans-serif; } 25 | 26 | td.node_name { font-family: Courier New, Helvetica, Sans-serif; font-size: 11px; padding-left: 10px; } 27 | td.node_name span { color: rgb( 2, 143, 65 ); font-weight:bold; } 28 | 29 | #popupcontent { position: absolute; visibility: hidden; overflow: hidden; border:1px solid #CCC; background-color:#F9F9F9; border:1px solid #333; padding:5px; overflow: scroll; } -------------------------------------------------------------------------------- /webenv/jscc_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abrobston/jscc/3e3043a7519b00dc9aebfc8f5850cca9237b97ec/webenv/jscc_logo.png -------------------------------------------------------------------------------- /webenv/jscc_logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abrobston/jscc/3e3043a7519b00dc9aebfc8f5850cca9237b97ec/webenv/jscc_logo_small.png -------------------------------------------------------------------------------- /wrap-end.js: -------------------------------------------------------------------------------- 1 | return require('jscc'); 2 | })); -------------------------------------------------------------------------------- /wrap-start.js: -------------------------------------------------------------------------------- 1 | (function(root, factory){ 2 | if (typeof define === 'function' && define.amd) { 3 | define([], factory); 4 | } else if (typeof module === 'object' && module.exports) { 5 | module.exports = factory(); 6 | } else { 7 | root.jscc = factory(); 8 | } 9 | }(this, function() { 10 | --------------------------------------------------------------------------------