Skip to content

Commit

Permalink
Code added.
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanyu committed Sep 13, 2014
1 parent 1816095 commit cc0a77f
Show file tree
Hide file tree
Showing 27 changed files with 1,196 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
/target
/rule-compiler.iml
/.idea
75 changes: 75 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>me.ivanyu</groupId>
<artifactId>rule-compiler</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>rule-compiler</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.3.1</version>
</dependency>

<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.3</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.3</version>
<executions>
<execution>
<goals>
<goal>antlr4</goal>
</goals>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
92 changes: 92 additions & 0 deletions src/main/antlr4/me/ivanyu/RuleSetGrammar.g4
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
grammar RuleSetGrammar;

/* Lexical rules */

IF : 'if' ;
THEN : 'then';

AND : 'and' ;
OR : 'or' ;

TRUE : 'true' ;
FALSE : 'false' ;

MULT : '*' ;
DIV : '/' ;
PLUS : '+' ;
MINUS : '-' ;

GT : '>' ;
GE : '>=' ;
LT : '<' ;
LE : '<=' ;
EQ : '=' ;

LPAREN : '(' ;
RPAREN : ')' ;

// DECIMAL, IDENTIFIER, COMMENTS, WS are set using regular expressions

DECIMAL : '-'?[0-9]+('.'[0-9]+)? ;

IDENTIFIER : [a-zA-Z_][a-zA-Z_0-9]* ;

SEMI : ';' ;

// COMMENT and WS are stripped from the output token stream by sending
// to a different channel 'skip'

COMMENT : '//' .+? ('\n'|EOF) -> skip ;

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


/* Parser rules */

rule_set : single_rule* EOF ;

single_rule : IF condition THEN conclusion SEMI ;

condition : logical_expr ;
conclusion : IDENTIFIER ;

logical_expr
: logical_expr AND logical_expr # LogicalExpressionAnd
| logical_expr OR logical_expr # LogicalExpressionOr
| comparison_expr # ComparisonExpression
| LPAREN logical_expr RPAREN # LogicalExpressionInParen
| logical_entity # LogicalEntity
;

comparison_expr : comparison_operand comp_operator comparison_operand
# ComparisonExpressionWithOperator
| LPAREN comparison_expr RPAREN # ComparisonExpressionParens
;

comparison_operand : arithmetic_expr
;

comp_operator : GT
| GE
| LT
| LE
| EQ
;

arithmetic_expr
: arithmetic_expr MULT arithmetic_expr # ArithmeticExpressionMult
| arithmetic_expr DIV arithmetic_expr # ArithmeticExpressionDiv
| arithmetic_expr PLUS arithmetic_expr # ArithmeticExpressionPlus
| arithmetic_expr MINUS arithmetic_expr # ArithmeticExpressionMinus
| MINUS arithmetic_expr # ArithmeticExpressionNegation
| LPAREN arithmetic_expr RPAREN # ArithmeticExpressionParens
| numeric_entity # ArithmeticExpressionNumericEntity
;

logical_entity : (TRUE | FALSE) # LogicalConst
| IDENTIFIER # LogicalVariable
;

numeric_entity : DECIMAL # NumericConst
| IDENTIFIER # NumericVariable
;
26 changes: 26 additions & 0 deletions src/main/java/me/ivanyu/CompilerApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package me.ivanyu;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import me.ivanyu.compiler.Compiler;
import me.ivanyu.pojos.RuleSet;

public class CompilerApplication {
public static void main(String[] args) {
Compiler compiler = new Compiler();
RuleSet ruleSet = compiler.compile("if -(A + 2) > 0.5 then be_careful;");

// JSON serialization
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);

String jsonString = null;
try {
jsonString = mapper.writeValueAsString(ruleSet);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println(jsonString);
}
}
25 changes: 25 additions & 0 deletions src/main/java/me/ivanyu/compiler/Compiler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package me.ivanyu.compiler;

import me.ivanyu.RuleSetGrammarLexer;
import me.ivanyu.RuleSetGrammarParser;
import me.ivanyu.pojos.RuleSet;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.TokenStream;

public class Compiler {
public RuleSet compile(String inputString) {
ANTLRInputStream input = new ANTLRInputStream(inputString);
RuleSetGrammarLexer lexer = new RuleSetGrammarLexer(input);
TokenStream tokens = new CommonTokenStream(lexer);
RuleSetGrammarParser parser = new RuleSetGrammarParser(tokens);

TreeBuilder treeBuilder = new TreeBuilder();
parser.addParseListener(treeBuilder);
parser.setErrorHandler(new ExceptionThrowingErrorHandler());

parser.rule_set();

return treeBuilder.getRuleSet();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package me.ivanyu.compiler;

import org.antlr.v4.runtime.*;

/**
* Error handler which throws exception on any parsing error.
*/
public class ExceptionThrowingErrorHandler extends DefaultErrorStrategy {
@Override
public void recover(Parser recognizer, RecognitionException e) {
throw new RuntimeException(e);
}

@Override
public Token recoverInline(Parser recognizer) throws RecognitionException {
throw new RuntimeException(new InputMismatchException(recognizer));
}

@Override
public void sync(Parser recognizer) throws RecognitionException {
}
}
Loading

0 comments on commit cc0a77f

Please sign in to comment.