mirror of https://github.com/t1meshift/js.git
Initial commit
commit
812f5107c3
|
@ -0,0 +1,108 @@
|
|||
.idea
|
||||
|
||||
### Python ###
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# Mr Developer
|
||||
.mr.developer.cfg
|
||||
.project
|
||||
.pydevproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
venv
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 Yury Kurlykov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,32 @@
|
|||
# Jasmine Snake
|
||||
Another JavaScript interpreter written on Python 3.
|
||||
|
||||
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
|
||||
[![SemVer: 2.0.0](https://img.shields.io/badge/SemVer-2.0.0-F8DE7E?labelColor=23261D)](https://semver.org/spec/v2.0.0.html)
|
||||
|
||||
## Requirements
|
||||
|
||||
- ANTLR 4
|
||||
- Colorama
|
||||
|
||||
To run tests:
|
||||
|
||||
- pylint
|
||||
- Tox
|
||||
|
||||
You can get ANTLR [here](https://www.antlr.org/), other dependencies could be installed with pip:
|
||||
```bash
|
||||
pip install -r requirements.txt # Use requirements-dev.txt if you want to run tests
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
```bash
|
||||
antlr4 -o jasminesnake/lex -package lex -Dlanguage=Python3 grammars/*.g4
|
||||
python -m jasminesnake
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
JavaScript grammar source:
|
||||
[https://github.com/antlr/grammars-v4/tree/master/javascript/javascript](https://github.com/antlr/grammars-v4/tree/master/javascript/javascript)
|
|
@ -0,0 +1,711 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 by Bart Kiers (original author) and Alexandre Vitorelli (contributor -> ported to CSharp)
|
||||
* Copyright (c) 2017-2020 by Ivan Kochurkin (Positive Technologies):
|
||||
added ECMAScript 6 support, cleared and transformed to the universal grammar.
|
||||
* Copyright (c) 2018 by Juan Alvarez (contributor -> ported to Go)
|
||||
* Copyright (c) 2019 by Student Main (contributor -> ES2020)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
lexer grammar JavaScriptLexer;
|
||||
|
||||
channels { ERROR }
|
||||
|
||||
options { superClass=JavaScriptBaseLexer; }
|
||||
|
||||
HashBangLine: { self.isStartOfFile()}? '#!' ~[\r\n\u2028\u2029]*; // only allowed at start
|
||||
MultiLineComment: '/*' .*? '*/' -> channel(HIDDEN);
|
||||
SingleLineComment: '//' ~[\r\n\u2028\u2029]* -> channel(HIDDEN);
|
||||
RegularExpressionLiteral: '/' RegularExpressionFirstChar RegularExpressionChar* {self.isRegexPossible()}? '/' IdentifierPart*;
|
||||
|
||||
OpenBracket: '[';
|
||||
CloseBracket: ']';
|
||||
OpenParen: '(';
|
||||
CloseParen: ')';
|
||||
OpenBrace: '{' {self.processOpenBrace()};
|
||||
CloseBrace: '}' {self.processCloseBrace()};
|
||||
SemiColon: ';';
|
||||
Comma: ',';
|
||||
Assign: '=';
|
||||
QuestionMark: '?';
|
||||
Colon: ':';
|
||||
Ellipsis: '...';
|
||||
Dot: '.';
|
||||
PlusPlus: '++';
|
||||
MinusMinus: '--';
|
||||
Plus: '+';
|
||||
Minus: '-';
|
||||
BitNot: '~';
|
||||
Not: '!';
|
||||
Multiply: '*';
|
||||
Divide: '/';
|
||||
Modulus: '%';
|
||||
Power: '**';
|
||||
NullCoalesce: '??';
|
||||
Hashtag: '#';
|
||||
RightShiftArithmetic: '>>';
|
||||
LeftShiftArithmetic: '<<';
|
||||
RightShiftLogical: '>>>';
|
||||
LessThan: '<';
|
||||
MoreThan: '>';
|
||||
LessThanEquals: '<=';
|
||||
GreaterThanEquals: '>=';
|
||||
Equals_: '==';
|
||||
NotEquals: '!=';
|
||||
IdentityEquals: '===';
|
||||
IdentityNotEquals: '!==';
|
||||
BitAnd: '&';
|
||||
BitXOr: '^';
|
||||
BitOr: '|';
|
||||
And: '&&';
|
||||
Or: '||';
|
||||
MultiplyAssign: '*=';
|
||||
DivideAssign: '/=';
|
||||
ModulusAssign: '%=';
|
||||
PlusAssign: '+=';
|
||||
MinusAssign: '-=';
|
||||
LeftShiftArithmeticAssign: '<<=';
|
||||
RightShiftArithmeticAssign: '>>=';
|
||||
RightShiftLogicalAssign: '>>>=';
|
||||
BitAndAssign: '&=';
|
||||
BitXorAssign: '^=';
|
||||
BitOrAssign: '|=';
|
||||
PowerAssign: '**=';
|
||||
ARROW: '=>';
|
||||
|
||||
/// Null Literals
|
||||
|
||||
NullLiteral: 'null';
|
||||
|
||||
/// Boolean Literals
|
||||
|
||||
BooleanLiteral: 'true'
|
||||
| 'false';
|
||||
|
||||
/// Numeric Literals
|
||||
|
||||
DecimalLiteral: DecimalIntegerLiteral '.' [0-9] [0-9_]* ExponentPart?
|
||||
| '.' [0-9] [0-9_]* ExponentPart?
|
||||
| DecimalIntegerLiteral ExponentPart?
|
||||
;
|
||||
|
||||
/// Numeric Literals
|
||||
|
||||
HexIntegerLiteral: '0' [xX] [0-9a-fA-F] HexDigit*;
|
||||
OctalIntegerLiteral: '0' [0-7]+ {not self.isStrictMode()}?;
|
||||
OctalIntegerLiteral2: '0' [oO] [0-7] [_0-7]*;
|
||||
BinaryIntegerLiteral: '0' [bB] [01] [_01]*;
|
||||
|
||||
BigHexIntegerLiteral: '0' [xX] [0-9a-fA-F] HexDigit* 'n';
|
||||
BigOctalIntegerLiteral: '0' [oO] [0-7] [_0-7]* 'n';
|
||||
BigBinaryIntegerLiteral: '0' [bB] [01] [_01]* 'n';
|
||||
BigDecimalIntegerLiteral: DecimalIntegerLiteral 'n';
|
||||
|
||||
/// Keywords
|
||||
|
||||
Break: 'break';
|
||||
Do: 'do';
|
||||
Typeof: 'typeof';
|
||||
Else: 'else';
|
||||
New: 'new';
|
||||
Var: 'var';
|
||||
Return: 'return';
|
||||
Void: 'void';
|
||||
Continue: 'continue';
|
||||
For: 'for';
|
||||
While: 'while';
|
||||
Function: 'function';
|
||||
This: 'this';
|
||||
Default: 'default';
|
||||
If: 'if';
|
||||
Throw: 'throw';
|
||||
Delete: 'delete';
|
||||
In: 'in';
|
||||
As: 'as';
|
||||
From: 'from';
|
||||
|
||||
/// Unused words in this project
|
||||
|
||||
//Instanceof: 'instanceof';
|
||||
//Case: 'case';
|
||||
//Catch: 'catch';
|
||||
//Finally: 'finally';
|
||||
//Switch: 'switch';
|
||||
//Debugger: 'debugger';
|
||||
//With: 'with';
|
||||
//Try: 'try';
|
||||
|
||||
/// Future Reserved Words
|
||||
|
||||
Class: 'class';
|
||||
Enum: 'enum';
|
||||
Extends: 'extends';
|
||||
Super: 'super';
|
||||
Const: 'const';
|
||||
Export: 'export';
|
||||
Import: 'import';
|
||||
|
||||
//Async: 'async';
|
||||
//Await: 'await';
|
||||
|
||||
/// The following tokens are also considered to be FutureReservedWords
|
||||
/// when parsing strict mode
|
||||
|
||||
Implements: 'implements' {self.isStrictMode()}?;
|
||||
StrictLet: 'let' {self.isStrictMode()}?;
|
||||
NonStrictLet: 'let' {not self.isStrictMode()}?;
|
||||
Private: 'private' {self.isStrictMode()}?;
|
||||
Public: 'public' {self.isStrictMode()}?;
|
||||
Interface: 'interface' {self.isStrictMode()}?;
|
||||
Package: 'package' {self.isStrictMode()}?;
|
||||
Protected: 'protected' {self.isStrictMode()}?;
|
||||
Static: 'static' {self.isStrictMode()}?;
|
||||
//Yield: 'yield' {self.isStrictMode()}?;
|
||||
|
||||
/// Identifier Names and Identifiers
|
||||
|
||||
Identifier: IdentifierStart IdentifierPart*;
|
||||
/// String Literals
|
||||
StringLiteral: ('"' DoubleStringCharacter* '"'
|
||||
| '\'' SingleStringCharacter* '\'') {self.processStringLiteral()}
|
||||
;
|
||||
|
||||
// TODO: `${`tmp`}`
|
||||
TemplateStringLiteral: '`' ('\\`' | ~'`')* '`';
|
||||
|
||||
WhiteSpaces: [\t\u000B\u000C\u0020\u00A0]+ -> channel(HIDDEN);
|
||||
|
||||
LineTerminator: [\r\n\u2028\u2029] -> channel(HIDDEN);
|
||||
|
||||
/// Comments
|
||||
|
||||
|
||||
HtmlComment: '<!--' .*? '-->' -> channel(HIDDEN);
|
||||
CDataComment: '<![CDATA[' .*? ']]>' -> channel(HIDDEN);
|
||||
UnexpectedCharacter: . -> channel(ERROR);
|
||||
|
||||
// Fragment rules
|
||||
|
||||
fragment DoubleStringCharacter
|
||||
: ~["\\\r\n]
|
||||
| '\\' EscapeSequence
|
||||
| LineContinuation
|
||||
;
|
||||
|
||||
fragment SingleStringCharacter
|
||||
: ~['\\\r\n]
|
||||
| '\\' EscapeSequence
|
||||
| LineContinuation
|
||||
;
|
||||
|
||||
fragment EscapeSequence
|
||||
: CharacterEscapeSequence
|
||||
| '0' // no digit ahead! TODO
|
||||
| HexEscapeSequence
|
||||
| UnicodeEscapeSequence
|
||||
| ExtendedUnicodeEscapeSequence
|
||||
;
|
||||
|
||||
fragment CharacterEscapeSequence
|
||||
: SingleEscapeCharacter
|
||||
| NonEscapeCharacter
|
||||
;
|
||||
|
||||
fragment HexEscapeSequence
|
||||
: 'x' HexDigit HexDigit
|
||||
;
|
||||
|
||||
fragment UnicodeEscapeSequence
|
||||
: 'u' HexDigit HexDigit HexDigit HexDigit
|
||||
| 'u' '{' HexDigit HexDigit+ '}'
|
||||
;
|
||||
|
||||
fragment ExtendedUnicodeEscapeSequence
|
||||
: 'u' '{' HexDigit+ '}'
|
||||
;
|
||||
|
||||
fragment SingleEscapeCharacter
|
||||
: ['"\\bfnrtv]
|
||||
;
|
||||
|
||||
fragment NonEscapeCharacter
|
||||
: ~['"\\bfnrtv0-9xu\r\n]
|
||||
;
|
||||
|
||||
fragment EscapeCharacter
|
||||
: SingleEscapeCharacter
|
||||
| [0-9]
|
||||
| [xu]
|
||||
;
|
||||
|
||||
fragment LineContinuation
|
||||
: '\\' [\r\n\u2028\u2029]
|
||||
;
|
||||
|
||||
fragment HexDigit
|
||||
: [_0-9a-fA-F]
|
||||
;
|
||||
|
||||
fragment DecimalIntegerLiteral
|
||||
: '0'
|
||||
| [1-9] [0-9_]*
|
||||
;
|
||||
|
||||
fragment ExponentPart
|
||||
: [eE] [+-]? [0-9_]+
|
||||
;
|
||||
|
||||
fragment IdentifierPart
|
||||
: IdentifierStart
|
||||
| UnicodeCombiningMark
|
||||
| UnicodeDigit
|
||||
| UnicodeConnectorPunctuation
|
||||
| '\u200C'
|
||||
| '\u200D'
|
||||
;
|
||||
|
||||
fragment IdentifierStart
|
||||
: UnicodeLetter
|
||||
| [$_]
|
||||
| '\\' UnicodeEscapeSequence
|
||||
;
|
||||
|
||||
fragment UnicodeLetter
|
||||
: [\u0041-\u005A]
|
||||
| [\u0061-\u007A]
|
||||
| [\u00AA]
|
||||
| [\u00B5]
|
||||
| [\u00BA]
|
||||
| [\u00C0-\u00D6]
|
||||
| [\u00D8-\u00F6]
|
||||
| [\u00F8-\u021F]
|
||||
| [\u0222-\u0233]
|
||||
| [\u0250-\u02AD]
|
||||
| [\u02B0-\u02B8]
|
||||
| [\u02BB-\u02C1]
|
||||
| [\u02D0-\u02D1]
|
||||
| [\u02E0-\u02E4]
|
||||
| [\u02EE]
|
||||
| [\u037A]
|
||||
| [\u0386]
|
||||
| [\u0388-\u038A]
|
||||
| [\u038C]
|
||||
| [\u038E-\u03A1]
|
||||
| [\u03A3-\u03CE]
|
||||
| [\u03D0-\u03D7]
|
||||
| [\u03DA-\u03F3]
|
||||
| [\u0400-\u0481]
|
||||
| [\u048C-\u04C4]
|
||||
| [\u04C7-\u04C8]
|
||||
| [\u04CB-\u04CC]
|
||||
| [\u04D0-\u04F5]
|
||||
| [\u04F8-\u04F9]
|
||||
| [\u0531-\u0556]
|
||||
| [\u0559]
|
||||
| [\u0561-\u0587]
|
||||
| [\u05D0-\u05EA]
|
||||
| [\u05F0-\u05F2]
|
||||
| [\u0621-\u063A]
|
||||
| [\u0640-\u064A]
|
||||
| [\u0671-\u06D3]
|
||||
| [\u06D5]
|
||||
| [\u06E5-\u06E6]
|
||||
| [\u06FA-\u06FC]
|
||||
| [\u0710]
|
||||
| [\u0712-\u072C]
|
||||
| [\u0780-\u07A5]
|
||||
| [\u0905-\u0939]
|
||||
| [\u093D]
|
||||
| [\u0950]
|
||||
| [\u0958-\u0961]
|
||||
| [\u0985-\u098C]
|
||||
| [\u098F-\u0990]
|
||||
| [\u0993-\u09A8]
|
||||
| [\u09AA-\u09B0]
|
||||
| [\u09B2]
|
||||
| [\u09B6-\u09B9]
|
||||
| [\u09DC-\u09DD]
|
||||
| [\u09DF-\u09E1]
|
||||
| [\u09F0-\u09F1]
|
||||
| [\u0A05-\u0A0A]
|
||||
| [\u0A0F-\u0A10]
|
||||
| [\u0A13-\u0A28]
|
||||
| [\u0A2A-\u0A30]
|
||||
| [\u0A32-\u0A33]
|
||||
| [\u0A35-\u0A36]
|
||||
| [\u0A38-\u0A39]
|
||||
| [\u0A59-\u0A5C]
|
||||
| [\u0A5E]
|
||||
| [\u0A72-\u0A74]
|
||||
| [\u0A85-\u0A8B]
|
||||
| [\u0A8D]
|
||||
| [\u0A8F-\u0A91]
|
||||
| [\u0A93-\u0AA8]
|
||||
| [\u0AAA-\u0AB0]
|
||||
| [\u0AB2-\u0AB3]
|
||||
| [\u0AB5-\u0AB9]
|
||||
| [\u0ABD]
|
||||
| [\u0AD0]
|
||||
| [\u0AE0]
|
||||
| [\u0B05-\u0B0C]
|
||||
| [\u0B0F-\u0B10]
|
||||
| [\u0B13-\u0B28]
|
||||
| [\u0B2A-\u0B30]
|
||||
| [\u0B32-\u0B33]
|
||||
| [\u0B36-\u0B39]
|
||||
| [\u0B3D]
|
||||
| [\u0B5C-\u0B5D]
|
||||
| [\u0B5F-\u0B61]
|
||||
| [\u0B85-\u0B8A]
|
||||
| [\u0B8E-\u0B90]
|
||||
| [\u0B92-\u0B95]
|
||||
| [\u0B99-\u0B9A]
|
||||
| [\u0B9C]
|
||||
| [\u0B9E-\u0B9F]
|
||||
| [\u0BA3-\u0BA4]
|
||||
| [\u0BA8-\u0BAA]
|
||||
| [\u0BAE-\u0BB5]
|
||||
| [\u0BB7-\u0BB9]
|
||||
| [\u0C05-\u0C0C]
|
||||
| [\u0C0E-\u0C10]
|
||||
| [\u0C12-\u0C28]
|
||||
| [\u0C2A-\u0C33]
|
||||
| [\u0C35-\u0C39]
|
||||
| [\u0C60-\u0C61]
|
||||
| [\u0C85-\u0C8C]
|
||||
| [\u0C8E-\u0C90]
|
||||
| [\u0C92-\u0CA8]
|
||||
| [\u0CAA-\u0CB3]
|
||||
| [\u0CB5-\u0CB9]
|
||||
| [\u0CDE]
|
||||
| [\u0CE0-\u0CE1]
|
||||
| [\u0D05-\u0D0C]
|
||||
| [\u0D0E-\u0D10]
|
||||
| [\u0D12-\u0D28]
|
||||
| [\u0D2A-\u0D39]
|
||||
| [\u0D60-\u0D61]
|
||||
| [\u0D85-\u0D96]
|
||||
| [\u0D9A-\u0DB1]
|
||||
| [\u0DB3-\u0DBB]
|
||||
| [\u0DBD]
|
||||
| [\u0DC0-\u0DC6]
|
||||
| [\u0E01-\u0E30]
|
||||
| [\u0E32-\u0E33]
|
||||
| [\u0E40-\u0E46]
|
||||
| [\u0E81-\u0E82]
|
||||
| [\u0E84]
|
||||
| [\u0E87-\u0E88]
|
||||
| [\u0E8A]
|
||||
| [\u0E8D]
|
||||
| [\u0E94-\u0E97]
|
||||
| [\u0E99-\u0E9F]
|
||||
| [\u0EA1-\u0EA3]
|
||||
| [\u0EA5]
|
||||
| [\u0EA7]
|
||||
| [\u0EAA-\u0EAB]
|
||||
| [\u0EAD-\u0EB0]
|
||||
| [\u0EB2-\u0EB3]
|
||||
| [\u0EBD-\u0EC4]
|
||||
| [\u0EC6]
|
||||
| [\u0EDC-\u0EDD]
|
||||
| [\u0F00]
|
||||
| [\u0F40-\u0F6A]
|
||||
| [\u0F88-\u0F8B]
|
||||
| [\u1000-\u1021]
|
||||
| [\u1023-\u1027]
|
||||
| [\u1029-\u102A]
|
||||
| [\u1050-\u1055]
|
||||
| [\u10A0-\u10C5]
|
||||
| [\u10D0-\u10F6]
|
||||
| [\u1100-\u1159]
|
||||
| [\u115F-\u11A2]
|
||||
| [\u11A8-\u11F9]
|
||||
| [\u1200-\u1206]
|
||||
| [\u1208-\u1246]
|
||||
| [\u1248]
|
||||
| [\u124A-\u124D]
|
||||
| [\u1250-\u1256]
|
||||
| [\u1258]
|
||||
| [\u125A-\u125D]
|
||||
| [\u1260-\u1286]
|
||||
| [\u1288]
|
||||
| [\u128A-\u128D]
|
||||
| [\u1290-\u12AE]
|
||||
| [\u12B0]
|
||||
| [\u12B2-\u12B5]
|
||||
| [\u12B8-\u12BE]
|
||||
| [\u12C0]
|
||||
| [\u12C2-\u12C5]
|
||||
| [\u12C8-\u12CE]
|
||||
| [\u12D0-\u12D6]
|
||||
| [\u12D8-\u12EE]
|
||||
| [\u12F0-\u130E]
|
||||
| [\u1310]
|
||||
| [\u1312-\u1315]
|
||||
| [\u1318-\u131E]
|
||||
| [\u1320-\u1346]
|
||||
| [\u1348-\u135A]
|
||||
| [\u13A0-\u13B0]
|
||||
| [\u13B1-\u13F4]
|
||||
| [\u1401-\u1676]
|
||||
| [\u1681-\u169A]
|
||||
| [\u16A0-\u16EA]
|
||||
| [\u1780-\u17B3]
|
||||
| [\u1820-\u1877]
|
||||
| [\u1880-\u18A8]
|
||||
| [\u1E00-\u1E9B]
|
||||
| [\u1EA0-\u1EE0]
|
||||
| [\u1EE1-\u1EF9]
|
||||
| [\u1F00-\u1F15]
|
||||
| [\u1F18-\u1F1D]
|
||||
| [\u1F20-\u1F39]
|
||||
| [\u1F3A-\u1F45]
|
||||
| [\u1F48-\u1F4D]
|
||||
| [\u1F50-\u1F57]
|
||||
| [\u1F59]
|
||||
| [\u1F5B]
|
||||
| [\u1F5D]
|
||||
| [\u1F5F-\u1F7D]
|
||||
| [\u1F80-\u1FB4]
|
||||
| [\u1FB6-\u1FBC]
|
||||
| [\u1FBE]
|
||||
| [\u1FC2-\u1FC4]
|
||||
| [\u1FC6-\u1FCC]
|
||||
| [\u1FD0-\u1FD3]
|
||||
| [\u1FD6-\u1FDB]
|
||||
| [\u1FE0-\u1FEC]
|
||||
| [\u1FF2-\u1FF4]
|
||||
| [\u1FF6-\u1FFC]
|
||||
| [\u207F]
|
||||
| [\u2102]
|
||||
| [\u2107]
|
||||
| [\u210A-\u2113]
|
||||
| [\u2115]
|
||||
| [\u2119-\u211D]
|
||||
| [\u2124]
|
||||
| [\u2126]
|
||||
| [\u2128]
|
||||
| [\u212A-\u212D]
|
||||
| [\u212F-\u2131]
|
||||
| [\u2133-\u2139]
|
||||
| [\u2160-\u2183]
|
||||
| [\u3005-\u3007]
|
||||
| [\u3021-\u3029]
|
||||
| [\u3031-\u3035]
|
||||
| [\u3038-\u303A]
|
||||
| [\u3041-\u3094]
|
||||
| [\u309D-\u309E]
|
||||
| [\u30A1-\u30FA]
|
||||
| [\u30FC-\u30FE]
|
||||
| [\u3105-\u312C]
|
||||
| [\u3131-\u318E]
|
||||
| [\u31A0-\u31B7]
|
||||
| [\u3400-\u4DBF]
|
||||
| [\u4E00-\u9FFF]
|
||||
| [\uA000-\uA48C]
|
||||
| [\uAC00]
|
||||
| [\uD7A3]
|
||||
| [\uF900-\uFA2D]
|
||||
| [\uFB00-\uFB06]
|
||||
| [\uFB13-\uFB17]
|
||||
| [\uFB1D]
|
||||
| [\uFB1F-\uFB28]
|
||||
| [\uFB2A-\uFB36]
|
||||
| [\uFB38-\uFB3C]
|
||||
| [\uFB3E]
|
||||
| [\uFB40-\uFB41]
|
||||
| [\uFB43-\uFB44]
|
||||
| [\uFB46-\uFBB1]
|
||||
| [\uFBD3-\uFD3D]
|
||||
| [\uFD50-\uFD8F]
|
||||
| [\uFD92-\uFDC7]
|
||||
| [\uFDF0-\uFDFB]
|
||||
| [\uFE70-\uFE72]
|
||||
| [\uFE74]
|
||||
| [\uFE76-\uFEFC]
|
||||
| [\uFF21-\uFF3A]
|
||||
| [\uFF41-\uFF5A]
|
||||
| [\uFF66-\uFFBE]
|
||||
| [\uFFC2-\uFFC7]
|
||||
| [\uFFCA-\uFFCF]
|
||||
| [\uFFD2-\uFFD7]
|
||||
| [\uFFDA-\uFFDC]
|
||||
;
|
||||
|
||||
fragment UnicodeCombiningMark
|
||||
: [\u0300-\u034E]
|
||||
| [\u0360-\u0362]
|
||||
| [\u0483-\u0486]
|
||||
| [\u0591-\u05A1]
|
||||
| [\u05A3-\u05B9]
|
||||
| [\u05BB-\u05BD]
|
||||
| [\u05BF]
|
||||
| [\u05C1-\u05C2]
|
||||
| [\u05C4]
|
||||
| [\u064B-\u0655]
|
||||
| [\u0670]
|
||||
| [\u06D6-\u06DC]
|
||||
| [\u06DF-\u06E4]
|
||||
| [\u06E7-\u06E8]
|
||||
| [\u06EA-\u06ED]
|
||||
| [\u0711]
|
||||
| [\u0730-\u074A]
|
||||
| [\u07A6-\u07B0]
|
||||
| [\u0901-\u0903]
|
||||
| [\u093C]
|
||||
| [\u093E-\u094D]
|
||||
| [\u0951-\u0954]
|
||||
| [\u0962-\u0963]
|
||||
| [\u0981-\u0983]
|
||||
| [\u09BC-\u09C4]
|
||||
| [\u09C7-\u09C8]
|
||||
| [\u09CB-\u09CD]
|
||||
| [\u09D7]
|
||||
| [\u09E2-\u09E3]
|
||||
| [\u0A02]
|
||||
| [\u0A3C]
|
||||
| [\u0A3E-\u0A42]
|
||||
| [\u0A47-\u0A48]
|
||||
| [\u0A4B-\u0A4D]
|
||||
| [\u0A70-\u0A71]
|
||||
| [\u0A81-\u0A83]
|
||||
| [\u0ABC]
|
||||
| [\u0ABE-\u0AC5]
|
||||
| [\u0AC7-\u0AC9]
|
||||
| [\u0ACB-\u0ACD]
|
||||
| [\u0B01-\u0B03]
|
||||
| [\u0B3C]
|
||||
| [\u0B3E-\u0B43]
|
||||
| [\u0B47-\u0B48]
|
||||
| [\u0B4B-\u0B4D]
|
||||
| [\u0B56-\u0B57]
|
||||
| [\u0B82-\u0B83]
|
||||
| [\u0BBE-\u0BC2]
|
||||
| [\u0BC6-\u0BC8]
|
||||
| [\u0BCA-\u0BCD]
|
||||
| [\u0BD7]
|
||||
| [\u0C01-\u0C03]
|
||||
| [\u0C3E-\u0C44]
|
||||
| [\u0C46-\u0C48]
|
||||
| [\u0C4A-\u0C4D]
|
||||
| [\u0C55-\u0C56]
|
||||
| [\u0C82-\u0C83]
|
||||
| [\u0CBE-\u0CC4]
|
||||
| [\u0CC6-\u0CC8]
|
||||
| [\u0CCA-\u0CCD]
|
||||
| [\u0CD5-\u0CD6]
|
||||
| [\u0D02-\u0D03]
|
||||
| [\u0D3E-\u0D43]
|
||||
| [\u0D46-\u0D48]
|
||||
| [\u0D4A-\u0D4D]
|
||||
| [\u0D57]
|
||||
| [\u0D82-\u0D83]
|
||||
| [\u0DCA]
|
||||
| [\u0DCF-\u0DD4]
|
||||
| [\u0DD6]
|
||||
| [\u0DD8-\u0DDF]
|
||||
| [\u0DF2-\u0DF3]
|
||||
| [\u0E31]
|
||||
| [\u0E34-\u0E3A]
|
||||
| [\u0E47-\u0E4E]
|
||||
| [\u0EB1]
|
||||
| [\u0EB4-\u0EB9]
|
||||
| [\u0EBB-\u0EBC]
|
||||
| [\u0EC8-\u0ECD]
|
||||
| [\u0F18-\u0F19]
|
||||
| [\u0F35]
|
||||
| [\u0F37]
|
||||
| [\u0F39]
|
||||
| [\u0F3E-\u0F3F]
|
||||
| [\u0F71-\u0F84]
|
||||
| [\u0F86-\u0F87]
|
||||
| [\u0F90-\u0F97]
|
||||
| [\u0F99-\u0FBC]
|
||||
| [\u0FC6]
|
||||
| [\u102C-\u1032]
|
||||
| [\u1036-\u1039]
|
||||
| [\u1056-\u1059]
|
||||
| [\u17B4-\u17D3]
|
||||
| [\u18A9]
|
||||
| [\u20D0-\u20DC]
|
||||
| [\u20E1]
|
||||
| [\u302A-\u302F]
|
||||
| [\u3099-\u309A]
|
||||
| [\uFB1E]
|
||||
| [\uFE20-\uFE23]
|
||||
;
|
||||
|
||||
fragment UnicodeDigit
|
||||
: [\u0030-\u0039]
|
||||
| [\u0660-\u0669]
|
||||
| [\u06F0-\u06F9]
|
||||
| [\u0966-\u096F]
|
||||
| [\u09E6-\u09EF]
|
||||
| [\u0A66-\u0A6F]
|
||||
| [\u0AE6-\u0AEF]
|
||||
| [\u0B66-\u0B6F]
|
||||
| [\u0BE7-\u0BEF]
|
||||
| [\u0C66-\u0C6F]
|
||||
| [\u0CE6-\u0CEF]
|
||||
| [\u0D66-\u0D6F]
|
||||
| [\u0E50-\u0E59]
|
||||
| [\u0ED0-\u0ED9]
|
||||
| [\u0F20-\u0F29]
|
||||
| [\u1040-\u1049]
|
||||
| [\u1369-\u1371]
|
||||
| [\u17E0-\u17E9]
|
||||
| [\u1810-\u1819]
|
||||
| [\uFF10-\uFF19]
|
||||
;
|
||||
|
||||
fragment UnicodeConnectorPunctuation
|
||||
: [\u005F]
|
||||
| [\u203F-\u2040]
|
||||
| [\u30FB]
|
||||
| [\uFE33-\uFE34]
|
||||
| [\uFE4D-\uFE4F]
|
||||
| [\uFF3F]
|
||||
| [\uFF65]
|
||||
;
|
||||
|
||||
fragment RegularExpressionFirstChar
|
||||
: ~[*\r\n\u2028\u2029\\/[]
|
||||
| RegularExpressionBackslashSequence
|
||||
| '[' RegularExpressionClassChar* ']'
|
||||
;
|
||||
|
||||
fragment RegularExpressionChar
|
||||
: ~[\r\n\u2028\u2029\\/[]
|
||||
| RegularExpressionBackslashSequence
|
||||
| '[' RegularExpressionClassChar* ']'
|
||||
;
|
||||
|
||||
fragment RegularExpressionClassChar
|
||||
: ~[\r\n\u2028\u2029\]\\]
|
||||
| RegularExpressionBackslashSequence
|
||||
;
|
||||
|
||||
fragment RegularExpressionBackslashSequence
|
||||
: '\\' ~[\r\n\u2028\u2029]
|
||||
;
|
|
@ -0,0 +1,511 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 by Bart Kiers (original author) and Alexandre Vitorelli (contributor -> ported to CSharp)
|
||||
* Copyright (c) 2017-2020 by Ivan Kochurkin (Positive Technologies):
|
||||
added ECMAScript 6 support, cleared and transformed to the universal grammar.
|
||||
* Copyright (c) 2018 by Juan Alvarez (contributor -> ported to Go)
|
||||
* Copyright (c) 2019 by Student Main (contributor -> ES2020)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
parser grammar JavaScriptParser;
|
||||
|
||||
options {
|
||||
tokenVocab=JavaScriptLexer;
|
||||
superClass=JavaScriptBaseParser;
|
||||
}
|
||||
|
||||
program
|
||||
: HashBangLine? sourceElements? EOF
|
||||
;
|
||||
|
||||
sourceElement
|
||||
: statement
|
||||
;
|
||||
|
||||
statement
|
||||
: block
|
||||
| variableStatement
|
||||
| importStatement
|
||||
| exportStatement
|
||||
| emptyStatement
|
||||
| classDeclaration
|
||||
| expressionStatement
|
||||
| ifStatement
|
||||
| iterationStatement
|
||||
| continueStatement
|
||||
| breakStatement
|
||||
| returnStatement
|
||||
//| yieldStatement
|
||||
//| withStatement
|
||||
//| labelledStatement
|
||||
//| switchStatement
|
||||
//| throwStatement
|
||||
//| tryStatement
|
||||
//| debuggerStatement
|
||||
| functionDeclaration
|
||||
;
|
||||
|
||||
block
|
||||
: '{' statementList? '}'
|
||||
;
|
||||
|
||||
statementList
|
||||
: statement+
|
||||
;
|
||||
|
||||
importStatement
|
||||
: Import importFromBlock
|
||||
;
|
||||
|
||||
importFromBlock
|
||||
: importDefault? (importNamespace | moduleItems) importFrom eos
|
||||
| StringLiteral eos
|
||||
;
|
||||
|
||||
moduleItems
|
||||
: '{' (aliasName ',')* (aliasName ','?)? '}'
|
||||
;
|
||||
|
||||
importDefault
|
||||
: aliasName ','
|
||||
;
|
||||
|
||||
importNamespace
|
||||
: ('*' | identifierName) (As identifierName)?
|
||||
;
|
||||
|
||||
importFrom
|
||||
: From StringLiteral
|
||||
;
|
||||
|
||||
aliasName
|
||||
: identifierName (As identifierName)?
|
||||
;
|
||||
|
||||
exportStatement
|
||||
: Export (exportFromBlock | declaration) eos # ExportDeclaration
|
||||
| Export Default singleExpression eos # ExportDefaultDeclaration
|
||||
;
|
||||
|
||||
exportFromBlock
|
||||
: importNamespace importFrom eos
|
||||
| moduleItems importFrom? eos
|
||||
;
|
||||
|
||||
declaration
|
||||
: variableStatement
|
||||
| classDeclaration
|
||||
| functionDeclaration
|
||||
;
|
||||
|
||||
variableStatement
|
||||
: variableDeclarationList eos
|
||||
;
|
||||
|
||||
variableDeclarationList
|
||||
: varModifier variableDeclaration (',' variableDeclaration)*
|
||||
;
|
||||
|
||||
variableDeclaration
|
||||
: assignable ('=' singleExpression)? // ECMAScript 6: Array & Object Matching
|
||||
;
|
||||
|
||||
emptyStatement
|
||||
: SemiColon
|
||||
;
|
||||
|
||||
expressionStatement
|
||||
: {self.notOpenBraceAndNotFunction()}? expressionSequence eos
|
||||
;
|
||||
|
||||
ifStatement
|
||||
: If '(' expressionSequence ')' statement (Else statement)?
|
||||
;
|
||||
|
||||
|
||||
iterationStatement
|
||||
: Do statement While '(' expressionSequence ')' eos # DoStatement
|
||||
| While '(' expressionSequence ')' statement # WhileStatement
|
||||
| For '(' (expressionSequence | variableDeclarationList)? ';' expressionSequence? ';' expressionSequence? ')' statement # ForStatement
|
||||
| For '(' (singleExpression | variableDeclarationList) In expressionSequence ')' statement # ForInStatement
|
||||
// strange, 'of' is an identifier. and self.p("of") not work in sometime.
|
||||
| For /*Await?*/ '(' (singleExpression | variableDeclarationList) identifier{self.p("of")}? expressionSequence ')' statement # ForOfStatement
|
||||
;
|
||||
|
||||
varModifier // let, const - ECMAScript 6
|
||||
: Var
|
||||
| let
|
||||
| Const
|
||||
;
|
||||
|
||||
continueStatement
|
||||
: Continue ({self.notLineTerminator()}? identifier)? eos
|
||||
;
|
||||
|
||||
breakStatement
|
||||
: Break ({self.notLineTerminator()}? identifier)? eos
|
||||
;
|
||||
|
||||
returnStatement
|
||||
: Return ({self.notLineTerminator()}? expressionSequence)? eos
|
||||
;
|
||||
|
||||
//yieldStatement
|
||||
// : Yield ({self.notLineTerminator()}? expressionSequence)? eos
|
||||
// ;
|
||||
//
|
||||
//withStatement
|
||||
// : With '(' expressionSequence ')' statement
|
||||
// ;
|
||||
//
|
||||
//switchStatement
|
||||
// : Switch '(' expressionSequence ')' caseBlock
|
||||
// ;
|
||||
|
||||
//caseBlock
|
||||
// : '{' caseClauses? (defaultClause caseClauses?)? '}'
|
||||
// ;
|
||||
//
|
||||
//caseClauses
|
||||
// : caseClause+
|
||||
// ;
|
||||
//
|
||||
//caseClause
|
||||
// : Case expressionSequence ':' statementList?
|
||||
// ;
|
||||
//
|
||||
//defaultClause
|
||||
// : Default ':' statementList?
|
||||
// ;
|
||||
//
|
||||
//labelledStatement
|
||||
// : identifier ':' statement
|
||||
// ;
|
||||
//
|
||||
//throwStatement
|
||||
// : Throw {self.notLineTerminator()}? expressionSequence eos
|
||||
// ;
|
||||
//
|
||||
//tryStatement
|
||||
// : Try block (catchProduction finallyProduction? | finallyProduction)
|
||||
// ;
|
||||
//
|
||||
//catchProduction
|
||||
// : Catch ('(' assignable? ')')? block
|
||||
// ;
|
||||
//
|
||||
//finallyProduction
|
||||
// : Finally block
|
||||
// ;
|
||||
//
|
||||
//debuggerStatement
|
||||
// : Debugger eos
|
||||
// ;
|
||||
|
||||
functionDeclaration
|
||||
: /*Async?*/ Function '*'? identifier '(' formalParameterList? ')' '{' functionBody '}'
|
||||
;
|
||||
|
||||
classDeclaration
|
||||
: Class identifier classTail
|
||||
;
|
||||
|
||||
classTail
|
||||
: (Extends singleExpression)? '{' classElement* '}'
|
||||
;
|
||||
|
||||
classElement
|
||||
: (Static | {self.n("static")}? identifier /*| Async*/)* (methodDefinition | assignable '=' objectLiteral ';')
|
||||
| emptyStatement
|
||||
| '#'? propertyName '=' singleExpression
|
||||
;
|
||||
|
||||
methodDefinition
|
||||
: '*'? '#'? propertyName '(' formalParameterList? ')' '{' functionBody '}'
|
||||
| '*'? '#'? getter '(' ')' '{' functionBody '}'
|
||||
| '*'? '#'? setter '(' formalParameterList? ')' '{' functionBody '}'
|
||||
;
|
||||
|
||||
formalParameterList
|
||||
: formalParameterArg (',' formalParameterArg)* (',' lastFormalParameterArg)?
|
||||
| lastFormalParameterArg
|
||||
;
|
||||
|
||||
formalParameterArg
|
||||
: assignable ('=' singleExpression)? // ECMAScript 6: Initialization
|
||||
;
|
||||
|
||||
lastFormalParameterArg // ECMAScript 6: Rest Parameter
|
||||
: Ellipsis singleExpression
|
||||
;
|
||||
|
||||
functionBody
|
||||
: sourceElements?
|
||||
;
|
||||
|
||||
sourceElements
|
||||
: sourceElement+
|
||||
;
|
||||
|
||||
arrayLiteral
|
||||
: ('[' elementList ']')
|
||||
;
|
||||
|
||||
elementList
|
||||
: ','* arrayElement? (','+ arrayElement)* ','* // Yes, everything is optional
|
||||
;
|
||||
|
||||
arrayElement
|
||||
: Ellipsis? singleExpression
|
||||
;
|
||||
|
||||
propertyAssignment
|
||||
: propertyName ':' singleExpression # PropertyExpressionAssignment
|
||||
| '[' singleExpression ']' ':' singleExpression # ComputedPropertyExpressionAssignment
|
||||
| /*Async?*/ '*'? propertyName '(' formalParameterList? ')' '{' functionBody '}' # FunctionProperty
|
||||
| getter '(' ')' '{' functionBody '}' # PropertyGetter
|
||||
| setter '(' formalParameterArg ')' '{' functionBody '}' # PropertySetter
|
||||
| Ellipsis? singleExpression # PropertyShorthand
|
||||
;
|
||||
|
||||
propertyName
|
||||
: identifierName
|
||||
| StringLiteral
|
||||
| numericLiteral
|
||||
| '[' singleExpression ']'
|
||||
;
|
||||
|
||||
arguments
|
||||
: '('(argument (',' argument)* ','?)?')'
|
||||
;
|
||||
|
||||
argument
|
||||
: Ellipsis? (singleExpression | identifier)
|
||||
;
|
||||
|
||||
expressionSequence
|
||||
: singleExpression (',' singleExpression)*
|
||||
;
|
||||
|
||||
singleExpression
|
||||
: anoymousFunction # FunctionExpression
|
||||
| Class identifier? classTail # ClassExpression
|
||||
| singleExpression '[' expressionSequence ']' # MemberIndexExpression
|
||||
| singleExpression '?'? '.' '#'? identifierName # MemberDotExpression
|
||||
| singleExpression arguments # ArgumentsExpression
|
||||
| New singleExpression arguments? # NewExpression
|
||||
| New '.' identifier # MetaExpression // new.target
|
||||
| singleExpression {self.notLineTerminator()}? '++' # PostIncrementExpression
|
||||
| singleExpression {self.notLineTerminator()}? '--' # PostDecreaseExpression
|
||||
| Delete singleExpression # DeleteExpression
|
||||
| Void singleExpression # VoidExpression
|
||||
| Typeof singleExpression # TypeofExpression
|
||||
| '++' singleExpression # PreIncrementExpression
|
||||
| '--' singleExpression # PreDecreaseExpression
|
||||
| '+' singleExpression # UnaryPlusExpression
|
||||
| '-' singleExpression # UnaryMinusExpression
|
||||
| '~' singleExpression # BitNotExpression
|
||||
| '!' singleExpression # NotExpression
|
||||
// | Await singleExpression # AwaitExpression
|
||||
| <assoc=right> singleExpression '**' singleExpression # PowerExpression
|
||||
| singleExpression ('*' | '/' | '%') singleExpression # MultiplicativeExpression
|
||||
| singleExpression ('+' | '-') singleExpression # AdditiveExpression
|
||||
| singleExpression '??' singleExpression # CoalesceExpression
|
||||
| singleExpression ('<<' | '>>' | '>>>') singleExpression # BitShiftExpression
|
||||
| singleExpression ('<' | '>' | '<=' | '>=') singleExpression # RelationalExpression
|
||||
// | singleExpression Instanceof singleExpression # InstanceofExpression
|
||||
| singleExpression In singleExpression # InExpression
|
||||
| singleExpression ('==' | '!=' | '===' | '!==') singleExpression # EqualityExpression
|
||||
| singleExpression '&' singleExpression # BitAndExpression
|
||||
| singleExpression '^' singleExpression # BitXOrExpression
|
||||
| singleExpression '|' singleExpression # BitOrExpression
|
||||
| singleExpression '&&' singleExpression # LogicalAndExpression
|
||||
| singleExpression '||' singleExpression # LogicalOrExpression
|
||||
| singleExpression '?' singleExpression ':' singleExpression # TernaryExpression
|
||||
| <assoc=right> singleExpression '=' singleExpression # AssignmentExpression
|
||||
| <assoc=right> singleExpression assignmentOperator singleExpression # AssignmentOperatorExpression
|
||||
| Import '(' singleExpression ')' # ImportExpression
|
||||
| singleExpression TemplateStringLiteral # TemplateStringExpression // ECMAScript 6
|
||||
// | yieldStatement # YieldExpression // ECMAScript 6
|
||||
| This # ThisExpression
|
||||
| identifier # IdentifierExpression
|
||||
| Super # SuperExpression
|
||||
| literal # LiteralExpression
|
||||
| arrayLiteral # ArrayLiteralExpression
|
||||
| objectLiteral # ObjectLiteralExpression
|
||||
| '(' expressionSequence ')' # ParenthesizedExpression
|
||||
;
|
||||
|
||||
assignable
|
||||
: identifier
|
||||
| arrayLiteral
|
||||
| objectLiteral
|
||||
;
|
||||
|
||||
objectLiteral
|
||||
: '{' (propertyAssignment (',' propertyAssignment)*)? ','? '}'
|
||||
;
|
||||
|
||||
anoymousFunction
|
||||
: functionDeclaration # FunctionDecl
|
||||
| /*Async?*/ Function '*'? '(' formalParameterList? ')' '{' functionBody '}' # AnoymousFunctionDecl
|
||||
| /*Async?*/ arrowFunctionParameters '=>' arrowFunctionBody # ArrowFunction
|
||||
;
|
||||
|
||||
arrowFunctionParameters
|
||||
: identifier
|
||||
| '(' formalParameterList? ')'
|
||||
;
|
||||
|
||||
arrowFunctionBody
|
||||
: singleExpression
|
||||
| '{' functionBody '}'
|
||||
;
|
||||
|
||||
assignmentOperator
|
||||
: '*='
|
||||
| '/='
|
||||
| '%='
|
||||
| '+='
|
||||
| '-='
|
||||
| '<<='
|
||||
| '>>='
|
||||
| '>>>='
|
||||
| '&='
|
||||
| '^='
|
||||
| '|='
|
||||
| '**='
|
||||
;
|
||||
|
||||
literal
|
||||
: NullLiteral
|
||||
| BooleanLiteral
|
||||
| StringLiteral
|
||||
| TemplateStringLiteral
|
||||
| RegularExpressionLiteral
|
||||
| numericLiteral
|
||||
| bigintLiteral
|
||||
;
|
||||
|
||||
numericLiteral
|
||||
: DecimalLiteral
|
||||
// | HexIntegerLiteral
|
||||
// | OctalIntegerLiteral
|
||||
// | OctalIntegerLiteral2
|
||||
// | BinaryIntegerLiteral
|
||||
;
|
||||
|
||||
bigintLiteral
|
||||
: BigDecimalIntegerLiteral
|
||||
// | BigHexIntegerLiteral
|
||||
// | BigOctalIntegerLiteral
|
||||
// | BigBinaryIntegerLiteral
|
||||
;
|
||||
|
||||
getter
|
||||
: identifier {self.p("get")}? propertyName
|
||||
;
|
||||
|
||||
setter
|
||||
: identifier {self.p("set")}? propertyName
|
||||
;
|
||||
|
||||
identifierName
|
||||
: identifier
|
||||
| reservedWord
|
||||
;
|
||||
|
||||
identifier
|
||||
: Identifier
|
||||
| NonStrictLet
|
||||
// | Async
|
||||
;
|
||||
|
||||
reservedWord
|
||||
: keyword
|
||||
| NullLiteral
|
||||
| BooleanLiteral
|
||||
;
|
||||
|
||||
keyword
|
||||
: Break
|
||||
| Do
|
||||
// | Instanceof
|
||||
| Typeof
|
||||
// | Case
|
||||
| Else
|
||||
| New
|
||||
| Var
|
||||
// | Catch
|
||||
// | Finally
|
||||
| Return
|
||||
| Void
|
||||
| Continue
|
||||
| For
|
||||
// | Switch
|
||||
| While
|
||||
// | Debugger
|
||||
| Function
|
||||
| This
|
||||
// | With
|
||||
| Default
|
||||
| If
|
||||
| Throw
|
||||
| Delete
|
||||
| In
|
||||
// | Try
|
||||
|
||||
| Class
|
||||
| Enum
|
||||
| Extends
|
||||
| Super
|
||||
| Const
|
||||
| Export
|
||||
| Import
|
||||
| Implements
|
||||
| let
|
||||
| Private
|
||||
| Public
|
||||
| Interface
|
||||
| Package
|
||||
| Protected
|
||||
| Static
|
||||
// | Yield
|
||||
// | Async
|
||||
// | Await
|
||||
| From
|
||||
| As
|
||||
;
|
||||
|
||||
let
|
||||
: NonStrictLet
|
||||
| StrictLet
|
||||
;
|
||||
|
||||
eos
|
||||
: SemiColon
|
||||
| EOF
|
||||
| {self.lineTerminatorAhead()}?
|
||||
| {self.closeBrace()}?
|
||||
;
|
|
@ -0,0 +1,3 @@
|
|||
__version__ = "0.0.1"
|
||||
|
||||
# TODO: make it usable as a module too
|
|
@ -0,0 +1,57 @@
|
|||
from jasminesnake import __version__
|
||||
|
||||
from antlr4 import *
|
||||
from .lex import JavaScriptLexer, JavaScriptParser
|
||||
|
||||
import argparse
|
||||
import colorama
|
||||
|
||||
|
||||
arg_parser = argparse.ArgumentParser(
|
||||
description="Jasmine Snake, another JS interpreter in Python",
|
||||
epilog="I hope you don't use it, **especially** in production.",
|
||||
)
|
||||
|
||||
arg_parser.add_argument("--snake", action="store_true", help="Print a snake")
|
||||
args = arg_parser.parse_args()
|
||||
|
||||
JSL = JavaScriptLexer.JavaScriptLexer
|
||||
JSP = JavaScriptParser.JavaScriptParser
|
||||
|
||||
|
||||
class WriteTreeListener(ParseTreeListener):
|
||||
def visitTerminal(self, node: TerminalNode):
|
||||
print("Visit Terminal: " + str(node) + " - " + repr(node))
|
||||
|
||||
|
||||
def main():
|
||||
colorama.init()
|
||||
|
||||
print("Jasmine Snake v{version}".format(version=__version__))
|
||||
|
||||
if args.snake:
|
||||
print(
|
||||
colorama.Style.DIM
|
||||
+ "[snake is sleeping now, so you see this stub. pretend you see the snake, please.]"
|
||||
)
|
||||
print(
|
||||
colorama.Fore.BLACK
|
||||
+ colorama.Back.YELLOW
|
||||
+ "Don't tread on me!"
|
||||
+ colorama.Back.RESET
|
||||
+ colorama.Fore.RESET
|
||||
)
|
||||
|
||||
print()
|
||||
|
||||
input_stream = InputStream('"use strict";var a;\na=2+a;')
|
||||
lexer = JSL(input_stream)
|
||||
stream = CommonTokenStream(lexer)
|
||||
parser = JSP(stream)
|
||||
print("Created parsers")
|
||||
tree = parser.program()
|
||||
ParseTreeWalker.DEFAULT.walk(WriteTreeListener(), tree)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,106 @@
|
|||
from antlr4 import *
|
||||
|
||||
relativeImport = False
|
||||
if __name__ is not None and "." in __name__:
|
||||
relativeImport = True
|
||||
|
||||
|
||||
class JavaScriptBaseLexer(Lexer):
|
||||
def __init__(self, *args, **kwargs):
|
||||
print("JavaScriptBaseLexerInit")
|
||||
super(JavaScriptBaseLexer, self).__init__(*args, **kwargs)
|
||||
|
||||
"""Stores values of nested modes. By default mode is strict or
|
||||
defined externally (useStrictDefault)"""
|
||||
self.scopeStrictModes = []
|
||||
self.lastToken: Token = None
|
||||
|
||||
"""Default value of strict mode
|
||||
Can be defined externally by setUseStrictDefault"""
|
||||
self.useStrictDefault = False
|
||||
|
||||
"""Current value of strict mode
|
||||
Can be defined during parsing, see StringFunctions.js and StringGlobal.js samples"""
|
||||
self.useStrictCurrent = False
|
||||
|
||||
def getStrictDefault(self) -> bool:
|
||||
return self.useStrictDefault
|
||||
|
||||
def setUseStrictDefault(self, value: bool):
|
||||
self.useStrictDefault = value
|
||||
self.useStrictCurrent = value
|
||||
|
||||
def isStrictMode(self):
|
||||
return self.useStrictCurrent
|
||||
|
||||
def isStartOfFile(self):
|
||||
return self.lastToken is None
|
||||
|
||||
def nextToken(self) -> Token:
|
||||
"""Return the next token from the character stream and records this last
|
||||
token in case it resides on the default channel. This recorded token
|
||||
is used to determine when the lexer could possibly match a regex
|
||||
literal. Also changes scopeStrictModes stack if tokenize special
|
||||
string 'use strict';
|
||||
|
||||
:return the next token from the character stream."""
|
||||
next_token: Token = super(JavaScriptBaseLexer, self).nextToken()
|
||||
|
||||
if next_token.channel == Token.DEFAULT_CHANNEL:
|
||||
self.lastToken = next_token
|
||||
|
||||
return next_token
|
||||
|
||||
def processOpenBrace(self):
|
||||
self.useStrictCurrent = bool(self.scopeStrictModes) and (
|
||||
True if self.scopeStrictModes[-1] else self.useStrictDefault
|
||||
)
|
||||
self.scopeStrictModes.append(self.useStrictCurrent)
|
||||
|
||||
def processCloseBrace(self):
|
||||
self.useStrictCurrent = bool(self.scopeStrictModes) and (
|
||||
True if self.scopeStrictModes.pop(-1) else self.useStrictDefault
|
||||
)
|
||||
|
||||
def processStringLiteral(self):
|
||||
if relativeImport:
|
||||
from .JavaScriptLexer import JavaScriptLexer
|
||||
else:
|
||||
from JavaScriptLexer import JavaScriptLexer
|
||||
if not self.lastToken or self.lastToken.type == JavaScriptLexer.OpenBrace:
|
||||
text = self.text
|
||||
if text == '"use strict"' or text == "'use strict'":
|
||||
if self.scopeStrictModes:
|
||||
self.scopeStrictModes.pop(-1)
|
||||
self.useStrictCurrent = True
|
||||
self.scopeStrictModes.append(self.useStrictCurrent)
|
||||
|
||||
def isRegexPossible(self) -> bool:
|
||||
"""Returns {@code true} if the lexer can match a regex literal. """
|
||||
if relativeImport:
|
||||
from .JavaScriptLexer import JavaScriptLexer
|
||||
else:
|
||||
from JavaScriptLexer import JavaScriptLexer
|
||||
|
||||
if not self.lastToken:
|
||||
# No token has been produced yet: at the start of the input,
|
||||
# no division is possible, so a regex literal _is_ possible.
|
||||
return True
|
||||
|
||||
if self.lastToken.type in [
|
||||
JavaScriptLexer.Identifier,
|
||||
JavaScriptLexer.NullLiteral,
|
||||
JavaScriptLexer.BooleanLiteral,
|
||||
JavaScriptLexer.This,
|
||||
JavaScriptLexer.CloseBracket,
|
||||
JavaScriptLexer.CloseParen,
|
||||
JavaScriptLexer.OctalIntegerLiteral,
|
||||
JavaScriptLexer.DecimalLiteral,
|
||||
JavaScriptLexer.HexIntegerLiteral,
|
||||
JavaScriptLexer.StringLiteral,
|
||||
JavaScriptLexer.PlusPlus,
|
||||
JavaScriptLexer.MinusMinus,
|
||||
]:
|
||||
return False
|
||||
|
||||
return True
|
|
@ -0,0 +1,108 @@
|
|||
from antlr4 import *
|
||||
|
||||
relativeImport = False
|
||||
if __name__ is not None and "." in __name__:
|
||||
relativeImport = True
|
||||
|
||||
|
||||
class JavaScriptBaseParser(Parser):
|
||||
@staticmethod
|
||||
def parser():
|
||||
if relativeImport:
|
||||
from .JavaScriptParser import JavaScriptParser
|
||||
else:
|
||||
from JavaScriptParser import JavaScriptParser
|
||||
return JavaScriptParser
|
||||
|
||||
def p(self, s: str) -> bool:
|
||||
return self.prev(s)
|
||||
|
||||
def prev(self, s: str) -> bool:
|
||||
return self._input.LT(-1).text == s
|
||||
|
||||
def n(self, s: str) -> bool:
|
||||
return self.next(s)
|
||||
|
||||
def next(self, s: str) -> bool:
|
||||
return self._input.LT(1).text == s
|
||||
|
||||
def notLineTerminator(self) -> bool:
|
||||
JavaScriptParser = self.parser()
|
||||
|
||||
return not self.here(JavaScriptParser.LineTerminator)
|
||||
|
||||
def notOpenBraceAndNotFunction(self) -> bool:
|
||||
JavaScriptParser = self.parser()
|
||||
|
||||
nextTokenType = self._input.LT(1).type
|
||||
return (
|
||||
nextTokenType != JavaScriptParser.OpenBrace
|
||||
and nextTokenType != JavaScriptParser.Function
|
||||
)
|
||||
|
||||
def closeBrace(self) -> bool:
|
||||
JavaScriptParser = self.parser()
|
||||
|
||||
return self._input.LT(1).type == JavaScriptParser.CloseBrace
|
||||
|
||||
def here(self, tokenType: int) -> bool:
|
||||
"""
|
||||
Returns {@code true} iff on the current index of the parser's
|
||||
token stream a token of the given {@code type} exists on the
|
||||
{@code HIDDEN} channel.
|
||||
:param:type:
|
||||
the type of the token on the {@code HIDDEN} channel
|
||||
to check.
|
||||
:return:{@code true} iff on the current index of the parser's
|
||||
token stream a token of the given {@code type} exists on the
|
||||
{@code HIDDEN} channel.
|
||||
"""
|
||||
# Get the token ahead of the current index.
|
||||
assert isinstance(self.getCurrentToken(), Token)
|
||||
possibleIndexEosToken: Token = self.getCurrentToken().tokenIndex - 1
|
||||
ahead = self._input.get(possibleIndexEosToken)
|
||||
|
||||
# Check if the token resides on the HIDDEN channel and if it's of the
|
||||
# provided type.
|
||||
return (ahead.channel == Lexer.HIDDEN) and (ahead.type == tokenType)
|
||||
|
||||
def lineTerminatorAhead(self) -> bool:
|
||||
"""
|
||||
Returns {@code true} iff on the current index of the parser's
|
||||
token stream a token exists on the {@code HIDDEN} channel which
|
||||
either is a line terminator, or is a multi line comment that
|
||||
contains a line terminator.
|
||||
|
||||
:return: {@code true} iff on the current index of the parser's
|
||||
token stream a token exists on the {@code HIDDEN} channel which
|
||||
either is a line terminator, or is a multi line comment that
|
||||
contains a line terminator.
|
||||
"""
|
||||
JavaScriptParser = self.parser()
|
||||
|
||||
# Get the token ahead of the current index.
|
||||
possibleIndexEosToken: Token = self.getCurrentToken().tokenIndex - 1
|
||||
ahead: Token = self._input.get(possibleIndexEosToken)
|
||||
|
||||
if ahead.channel != Lexer.HIDDEN:
|
||||
# We're only interested in tokens on the HIDDEN channel.
|
||||
return False
|
||||
|
||||
if ahead.type == JavaScriptParser.LineTerminator:
|
||||
# There is definitely a line terminator ahead.
|
||||
return True
|
||||
|
||||
if ahead.type == JavaScriptParser.WhiteSpaces:
|
||||
# Get the token ahead of the current whitespaces.
|
||||
possibleIndexEosToken = self.getCurrentToken().tokenIndex - 2
|
||||
ahead = self._input.get(possibleIndexEosToken)
|
||||
|
||||
# Get the token's text and type.
|
||||
text = ahead.text
|
||||
tokenType = ahead.type
|
||||
|
||||
# Check if the token is, or contains a line terminator.
|
||||
return (
|
||||
tokenType == JavaScriptParser.MultiLineComment
|
||||
and (text.contains("\r") or text.contains("\n"))
|
||||
) or (tokenType == JavaScriptParser.LineTerminator)
|
|
@ -0,0 +1,3 @@
|
|||
-r requirements.txt
|
||||
tox==3.14.6
|
||||
pytest==5.4.1
|
|
@ -0,0 +1,2 @@
|
|||
antlr4-python3-runtime
|
||||
colorama==0.4.3
|
|
@ -0,0 +1,30 @@
|
|||
from setuptools import setup
|
||||
from jasminesnake import __version__
|
||||
|
||||
with open("README.md", "r") as fh:
|
||||
long_description = fh.read()
|
||||
|
||||
with open("requirements.txt") as f:
|
||||
requirements = f.readlines()
|
||||
|
||||
setup(
|
||||
name="jasminesnake",
|
||||
version=__version__,
|
||||
packages=["jasminesnake"],
|
||||
url="https://github.com/t1meshift/js",
|
||||
license="MIT",
|
||||
author="Yury Kurlykov",
|
||||
author_email="sh1ftr@protonmail.ch",
|
||||
description="Another JavaScript interpreter written in Python",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
classifiers=[
|
||||
"Programming Language :: Python :: 3",
|
||||
# "Programming Language :: JavaScript",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Development Status :: 2 - Pre-Alpha",
|
||||
],
|
||||
python_requires=">=3.8",
|
||||
install_requires=requirements,
|
||||
entry_points={"console_scripts": ["jasminesnake = jasminesnake.__main__:main"]},
|
||||
)
|
Loading…
Reference in New Issue