Compare commits

..

5 Commits

Author SHA1 Message Date
00a3f79fb8 feat: yjs keyword sharable 2023-06-25 16:35:21 +08:00
Frank.R.Wu
8e06d0bc81 build: config spotless plugin and reformat code 2023-06-15 11:08:04 +08:00
CaiHQ
b60e81e1a1 support interface 2023-06-09 18:23:51 +08:00
haoeliu@foxmail.com
645f863d7b update syntax tree 2023-01-08 19:39:32 +08:00
CaiHQ
309a60e561 add gitignore 2022-05-05 13:43:20 +08:00
12 changed files with 150 additions and 55 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
/build/
/gen/ /gen/
/input/JavaScriptLexer.tokens /input/JavaScriptLexer.tokens
/input/gen /input/gen

4
README.md Normal file
View File

@ -0,0 +1,4 @@
1.修改input下面的`YJSParser.g4`
2.运行`AntlrGenLexerTool`
3.运行`AntlrGenParserTool`
4.运行`CleanTempFiles`

View File

@ -3,6 +3,8 @@ plugins {
id 'java-library' id 'java-library'
} }
apply from: '../spotless.gradle'
sourceSets { sourceSets {
main { main {
java { java {

View File

@ -1,23 +1,23 @@
package org.bdware.sc.parser; package org.bdware.sc.parser;
import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.*;
import java.util.Stack; import java.util.Stack;
public abstract class JavaScriptBaseLexer extends Lexer
{ public abstract class JavaScriptBaseLexer extends Lexer {
/** /**
* Stores values of nested modes. By default mode is strict or * Stores values of nested modes. By default mode is strict or defined externally
* defined externally (useStrictDefault) * (useStrictDefault)
*/ */
private Stack<Boolean> scopeStrictModes = new Stack<Boolean>(); private Stack<Boolean> scopeStrictModes = new Stack<Boolean>();
private Token lastToken = null; private Token lastToken = null;
/** /**
* Default value of strict mode * Default value of strict mode Can be defined externally by setUseStrictDefault
* Can be defined externally by setUseStrictDefault
*/ */
private boolean useStrictDefault = false; private boolean useStrictDefault = false;
/** /**
* Current value of strict mode * Current value of strict mode Can be defined during parsing, see StringFunctions.js and
* Can be defined during parsing, see StringFunctions.js and StringGlobal.js samples * StringGlobal.js samples
*/ */
private boolean useStrictCurrent = false; private boolean useStrictCurrent = false;
@ -39,10 +39,9 @@ public abstract class JavaScriptBaseLexer extends Lexer
} }
/** /**
* Return the next token from the character stream and records this last * Return the next token from the character stream and records this last token in case it
* token in case it resides on the default channel. This recorded token * resides on the default channel. This recorded token is used to determine when the lexer could
* is used to determine when the lexer could possibly match a regex * possibly match a regex literal. Also changes scopeStrictModes stack if tokenize special
* literal. Also changes scopeStrictModes stack if tokenize special
* string 'use strict'; * string 'use strict';
* *
* @return the next token from the character stream. * @return the next token from the character stream.
@ -59,24 +58,20 @@ public abstract class JavaScriptBaseLexer extends Lexer
return next; return next;
} }
protected void ProcessOpenBrace() protected void ProcessOpenBrace() {
{ useStrictCurrent =
useStrictCurrent = scopeStrictModes.size() > 0 && scopeStrictModes.peek() ? true : useStrictDefault; scopeStrictModes.size() > 0 && scopeStrictModes.peek() ? true : useStrictDefault;
scopeStrictModes.push(useStrictCurrent); scopeStrictModes.push(useStrictCurrent);
} }
protected void ProcessCloseBrace() protected void ProcessCloseBrace() {
{
useStrictCurrent = scopeStrictModes.size() > 0 ? scopeStrictModes.pop() : useStrictDefault; useStrictCurrent = scopeStrictModes.size() > 0 ? scopeStrictModes.pop() : useStrictDefault;
} }
protected void ProcessStringLiteral() protected void ProcessStringLiteral() {
{ if (lastToken == null || lastToken.getType() == JavaScriptLexer.OpenBrace) {
if (lastToken == null || lastToken.getType() == JavaScriptLexer.OpenBrace)
{
String text = getText(); String text = getText();
if (text.equals("\"use strict\"") || text.equals("'use strict'")) if (text.equals("\"use strict\"") || text.equals("'use strict'")) {
{
if (scopeStrictModes.size() > 0) if (scopeStrictModes.size() > 0)
scopeStrictModes.pop(); scopeStrictModes.pop();
useStrictCurrent = true; useStrictCurrent = true;

View File

@ -3,8 +3,8 @@ package org.bdware.sc.parser;
import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.*;
/** /**
* All parser methods that used in grammar (p, prev, notLineTerminator, etc.) * All parser methods that used in grammar (p, prev, notLineTerminator, etc.) should start with
* should start with lower case char similar to parser rules. * lower case char similar to parser rules.
*/ */
public abstract class JavaScriptBaseParser extends Parser { public abstract class JavaScriptBaseParser extends Parser {
public JavaScriptBaseParser(TokenStream input) { public JavaScriptBaseParser(TokenStream input) {
@ -53,12 +53,12 @@ public abstract class JavaScriptBaseParser extends Parser {
} }
/** /**
* Returns {@code true} iff on the current index of the parser's token stream a * Returns {@code true} iff on the current index of the parser's token stream a token of the
* token of the given {@code type} exists on the {@code HIDDEN} channel. * given {@code type} exists on the {@code HIDDEN} channel.
* *
* @param type the type of the token on the {@code HIDDEN} channel to check. * @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 * @return {@code true} iff on the current index of the parser's token stream a token of the
* token of the given {@code type} exists on the {@code HIDDEN} channel. * given {@code type} exists on the {@code HIDDEN} channel.
*/ */
private boolean here(final int type) { private boolean here(final int type) {
@ -72,14 +72,13 @@ public abstract class JavaScriptBaseParser extends Parser {
} }
/** /**
* Returns {@code true} iff on the current index of the parser's token stream a * Returns {@code true} iff on the current index of the parser's token stream a token exists on
* token exists on the {@code HIDDEN} channel which either is a line terminator, * the {@code HIDDEN} channel which either is a line terminator, or is a multi line comment that
* or is a multi line comment that contains a line terminator. * contains a line terminator.
* *
* @return {@code true} iff on the current index of the parser's token stream a * @return {@code true} iff on the current index of the parser's token stream a token exists on
* token exists on the {@code HIDDEN} channel which either is a line * the {@code HIDDEN} channel which either is a line terminator, or is a multi line
* terminator, or is a multi line comment that contains a line * comment that contains a line terminator.
* terminator.
*/ */
protected boolean lineTerminatorAhead() { protected boolean lineTerminatorAhead() {

View File

@ -140,6 +140,7 @@ In: 'in';
Try: 'try'; Try: 'try';
Event: 'event'; Event: 'event';
AtToken: '@'; AtToken: '@';
Sharable: 'sharable';
/// Event Semantics /// Event Semantics
@ -168,6 +169,7 @@ Import: 'import';
Contract: 'contract'; Contract: 'contract';
Module: 'module'; Module: 'module';
Oracle: 'oracle'; Oracle: 'oracle';
DoipModule: 'doipmodule';
/// The following tokens are also considered to be FutureReservedWords /// The following tokens are also considered to be FutureReservedWords
/// when parsing strict mode /// when parsing strict mode

View File

@ -38,7 +38,7 @@ program
; ;
contractDeclar contractDeclar
: annotations? (Contract|Module|Oracle) Identifier '{' clzOrFunctionDeclaration+ '}' : annotations? (Contract|Module|Oracle|DoipModule) Identifier '{' clzOrFunctionDeclaration+ '}'
; ;
annotations annotations
@ -61,8 +61,15 @@ annotationLiteral
clzOrFunctionDeclaration clzOrFunctionDeclaration
:classDeclaration :classDeclaration
|functionDeclaration |functionDeclaration
|interfaceDeclaration
|eventDeclaration |eventDeclaration
|sharableDeclaration
; ;
interfaceDeclaration
: annotations? Interface Identifier '(' formalParameterList? ')' eos
;
eventDeclaration eventDeclaration
:Event eventGlobalOrLocal? Identifier SemiColon :Event eventGlobalOrLocal? Identifier SemiColon
|Event eventGlobalOrLocal? Identifier '(' eventSemantics? ')' SemiColon |Event eventGlobalOrLocal? Identifier '(' eventSemantics? ')' SemiColon
@ -114,6 +121,17 @@ block
statementList statementList
: statement+ : statement+
; ;
sharableDeclaration
: sharableStatement
;
sharableStatement
: sharableModifier variableDeclarationList eos
;
sharableModifier // let, const - ECMAScript 6
: Sharable
;
variableStatement variableStatement
: varModifier variableDeclarationList eos : varModifier variableDeclarationList eos
@ -435,6 +453,7 @@ keyword
| Protected | Protected
| Static | Static
| Yield | Yield
| Sharable
; ;
eos eos

View File

@ -0,0 +1,27 @@
import org.antlr.v4.Tool;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
public class AntlrGenLexerTool {
public static void main(String[] args) throws IOException {
processLexer();
}
private static void processLexer() {
String g5 = "JavaScriptLexer.g4";
String pkg = "org.bdware.sc.parser";
File from = new File("./genparser/input/" + g5);
File out = new File(g5);
out.delete();
try {
Files.copy(from.toPath(), out.toPath());
Tool.main(new String[] {g5, "-package", pkg, "-o",
"./common/src/main/gen/" + pkg.replaceAll("\\.", "/"), "-visitor"});
new File(g5).delete();
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,34 @@
import org.antlr.v4.Tool;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
public class AntlrGenParserTool {
public static void main(String[] args) throws IOException {
processParser();
}
private static void processParser() {
String g4 = "YJSParser.g4";
String pkg;
// g4 = "ExprParser.g4";
if (g4.equals("YJSParser.g4"))
pkg = "org.bdware.sc.parser";
else
pkg = "org.bdware.sc.parser.test";
System.out.println("GenerateAt:" + "./common/src/main/gen/" + pkg.replaceAll("\\.", "/"));
File from = new File("./genparser/input/" + g4);
File out = new File(g4);
out.delete();
try {
Files.copy(from.toPath(), out.toPath());
} catch (Exception e) {
e.printStackTrace();
}
Tool.main(new String[] {g4, "-package", pkg, "-o",
"./common/src/main/gen/" + pkg.replaceAll("\\.", "/"), "-visitor"});
}
}

View File

@ -5,12 +5,10 @@ import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
public class AntlrTool { public class AntlrTool {
@SuppressWarnings("deprecation")
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
processLexer(); processLexer();
// processParser(); // processParser();
} }
private static void processParser() { private static void processParser() {
@ -33,7 +31,8 @@ public class AntlrTool {
e.printStackTrace(); e.printStackTrace();
} }
// Tool.main(new String[] {}); // Tool.main(new String[] {});
Tool.main(new String[]{g4, "-package", pkg, "-o", "./common/src/main/gen/" + pkg.replaceAll("\\.", "/"), "-visitor"}); Tool.main(new String[] {g4, "-package", pkg, "-o",
"./common/src/main/gen/" + pkg.replaceAll("\\.", "/"), "-visitor"});
// Tool.main(new String[] { g5, "-package", pkg, "-o", "./gen/" + // Tool.main(new String[] { g5, "-package", pkg, "-o", "./gen/" +
// pkg.replaceAll("\\.", "/"), "-visitor" }); // pkg.replaceAll("\\.", "/"), "-visitor" });
@ -50,8 +49,8 @@ public class AntlrTool {
out.delete(); out.delete();
try { try {
Files.copy(from.toPath(), out.toPath()); Files.copy(from.toPath(), out.toPath());
Tool.main(new String[]{g5, "-package", pkg, "-o", "./common/src/main/gen/" + Tool.main(new String[] {g5, "-package", pkg, "-o",
pkg.replaceAll("\\.", "/"), "-visitor"}); "./common/src/main/gen/" + pkg.replaceAll("\\.", "/"), "-visitor"});
new File(g5).delete(); new File(g5).delete();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -0,0 +1,13 @@
import java.io.File;
import java.io.IOException;
public class CleanTempFiles {
public static void main(String[] args) throws IOException {
String g4 = "YJSParser.g4";
File out = new File(g4);
out.delete();
String g5 = "JavaScriptLexer.g4";
out = new File(g5);
out.delete();
}
}