Skip to content
Permalink
Browse files

Add initial ANTLR setup + lex/parser

  • Loading branch information
octylFractal committed Oct 13, 2019
1 parent 21f3d96 commit 7d52374fc01cf9c29cd9fe7a59b0d101b535886a
@@ -1,7 +1,10 @@
import org.gradle.plugins.ide.idea.model.IdeaModel

plugins {
id("java-library")
id("net.ltgt.apt-eclipse")
id("net.ltgt.apt-idea")
id("antlr")
}

applyPlatformAndCoreConfiguration()
@@ -23,6 +26,10 @@ dependencies {
"compile"("org.slf4j:slf4j-api:1.7.26")
"compile"("it.unimi.dsi:fastutil:8.2.1")

val antlrVersion = "4.7.2"
"antlr"("org.antlr:antlr4:$antlrVersion")
"implementation"("org.antlr:antlr4-runtime:$antlrVersion")

"compileOnly"(project(":worldedit-libs:core:ap"))
"annotationProcessor"(project(":worldedit-libs:core:ap"))
// ensure this is on the classpath for the AP
@@ -36,6 +43,26 @@ tasks.withType<JavaCompile>().configureEach {
options.compilerArgs.add("-Aarg.name.key.prefix=")
}

tasks.named<AntlrTask>("generateGrammarSource").configure {
val pkg = "com.sk89q.worldedit.antlr"
outputDirectory = file("build/generated-src/antlr/main/${pkg.replace('.', '/')}")
arguments = listOf(
"-visitor", "-package", pkg,
"-Xexact-output-dir"
)
}

// Give intellij info about where ANTLR code comes from
plugins.withId("idea") {
configure<IdeaModel> {
afterEvaluate {
module.sourceDirs.add(file("src/main/antlr"))
module.sourceDirs.add(file("build/generated-src/antlr/main"))
module.generatedSourceDirs.add(file("build/generated-src/antlr/main"))
}
}
}

sourceSets {
main {
java {
@@ -0,0 +1,186 @@
grammar Expression;

// Lexer tokens:

PLUS : '+' ;
MINUS : '-' ;
TIMES : '*' ;
DIVIDE : '/' ;
MODULO : '%' ;
POWER : '^' | '**' ;
LEFT_SHIFT : '<<' ;
RIGHT_SHIFT : '>>' ;
ASSIGN : '=' ;
COMPLEMENT : '~' ;

PLUS_ASSIGN : '+=' ;
MINUS_ASSIGN : '-=' ;
TIMES_ASSIGN : '*=' ;
DIVIDE_ASSIGN : '/=' ;
MODULO_ASSIGN : '%=' ;
POWER_ASSIGN : '^=' ;

EQUAL : '==' ;
NOT_EQUAL : '!=' ;
NEAR : '~=' ;
LESS_THAN : '<' ;
LESS_THAN_OR_EQUAL : '<=' ;
GREATER_THAN : '>' ;
GREATER_THAN_OR_EQUAL : '>=' ;
// SC = "Short Circuit"
// Non-SC variants not currently implemented.
AND_SC : '&&' ;
OR_SC : '||' ;

INCREMENT : '++' ;
DECREMENT : '--' ;

COMMA : ',' ;
OPEN_PAREN : '(' ;
CLOSE_PAREN : ')' ;
OPEN_BRACKET : '{' ;
CLOSE_BRACKET : '}' ;
SEMI_COLON : ';' ;
QUESTION_MARK : '?' ;
COLON : ':' ;
EXCLAMATION_MARK : '!' ;

IF : 'if' ;
ELSE : 'else' ;
WHILE : 'while' ;
DO : 'do' ;
FOR : 'for' ;
BREAK : 'break' ;
CONTINUE : 'continue' ;
RETURN : 'return' ;
SWITCH : 'switch' ;
CASE : 'case' ;
DEFAULT : 'default' ;

fragment DIGIT : [0-9] ;
fragment SIGN : [+-] ;
fragment EXP_CHAR : [eE] ;
fragment DECIMAL : '.' DIGIT+ ( EXP_CHAR SIGN? DIGIT+ )? ;

// All numbers are treated the same. No int/dec divide.
NUMBER : SIGN? ( DIGIT+ DECIMAL? | DECIMAL ) ;

ID : [A-Za-z] [0-9A-Za-z_]* ;

WS : [ \t\r\n\u000C]+ -> skip ;

// Parser rules:

/**
* All statements parseable from the input. Forces consumption of EOF token.
*/
allStatements : statements EOF ;

statements : statement+ ;

statement
: block
| ifStatement
| whileStatement
| doStatement
| forStatement
| breakStatement
| continueStatement
| returnStatement
| switchStatement
| expressionStatement
| SEMI_COLON
;

block : '{' statements '}' ;

ifStatement : IF '(' expression ')' statement ( ELSE statement ) ;

whileStatement : WHILE '(' expression ')' statement ;

doStatement : DO statement WHILE '(' expression ')' SEMI_COLON ;

forStatement
: FOR '('
// C-style for loop
( expression ';' expression ';' expression
// Range for loop
| ID ASSIGN ID ',' ID
)
')' statement ;

breakStatement : BREAK ;

continueStatement : CONTINUE ;

returnStatement : RETURN expression? ;

switchStatement : SWITCH '(' expression ')' '{' (switchLabel ':' statements )+ '}' ;

switchLabel
: CASE constantExpression
| DEFAULT
;

expressionStatement : expression SEMI_COLON ;

expression
: constantExpression
| functionCall
| identifierExpression
| '(' expression ')'
| unaryOp expression
| identifierExpression binaryAssignOp expression
| expression binaryOp expression
| expression postUnaryOp
;

constantExpression : NUMBER ;

functionCall : ID '(' (expression ( ',' expression )*)? ')' ;

identifierExpression : ID ;

unaryOp
: MINUS
| EXCLAMATION_MARK
| COMPLEMENT
| INCREMENT
| DECREMENT
;

postUnaryOp
: INCREMENT
| DECREMENT
| EXCLAMATION_MARK
;

binaryOp
: POWER
| TIMES
| DIVIDE
| MODULO
| PLUS
| MINUS
| LEFT_SHIFT
| RIGHT_SHIFT
| LESS_THAN
| GREATER_THAN
| LESS_THAN_OR_EQUAL
| GREATER_THAN_OR_EQUAL
| EQUAL
| NOT_EQUAL
| NEAR
| AND_SC
| OR_SC
;

binaryAssignOp
: ASSIGN
| PLUS_ASSIGN
| MINUS_ASSIGN
| TIMES_ASSIGN
| DIVIDE_ASSIGN
| MODULO_ASSIGN
| POWER_ASSIGN
;

0 comments on commit 7d52374

Please sign in to comment.
You can’t perform that action at this time.