Created
August 12, 2012 08:13
-
-
Save nakamura-to/3330618 to your computer and use it in GitHub Desktop.
Translator with ANTLR
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
i = 1 | |
while i < 10 { // even number? | |
if i % 2 == 2 { | |
even = even + 1 | |
} else { | |
odd = odd + 1 | |
} | |
i = i + 1 | |
} | |
even + odd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
group Js; | |
program(vars, text) ::= << | |
(function () { | |
var <vars : {var | <var> = 0}; separator=", ">; | |
<text> | |
})(); | |
>> | |
if(cond, thenBlock, elseBlock) ::= << | |
if (<cond>) { | |
<thenBlock> | |
} <if(elseBlock)> else { | |
<elseBlock> | |
}<endif> | |
>> | |
while(cond, block) ::= << | |
while (<cond>) { | |
<block> | |
} | |
>> | |
assign(id, expr) ::= << | |
<id> = <expr> | |
>> | |
simple(text) ::= << | |
<text>; | |
>> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.FileReader; | |
import org.antlr.runtime.ANTLRFileStream; | |
import org.antlr.runtime.CharStream; | |
import org.antlr.runtime.CommonTokenStream; | |
import org.antlr.runtime.tree.CommonTree; | |
import org.antlr.runtime.tree.CommonTreeNodeStream; | |
import org.antlr.stringtemplate.StringTemplateGroup; | |
public class Main { | |
public static void main(String[] args) throws Exception { | |
FileReader reader = new FileReader("./bin/Js.stg"); | |
StringTemplateGroup templates = new StringTemplateGroup(reader); | |
CharStream input = new ANTLRFileStream("./bin/input.txt"); | |
StoneLexer lexer = new StoneLexer(input); | |
CommonTokenStream tokens = new CommonTokenStream(lexer); | |
StoneParser parser = new StoneParser(tokens); | |
CommonTree tree = parser.program().tree; | |
CommonTreeNodeStream nodes = new CommonTreeNodeStream(tree); | |
nodes.setTokenStream(tokens); | |
StoneToJs walker = new StoneToJs(nodes); | |
walker.setTemplateLib(templates); | |
Object t = walker.program(parser.vars).getTemplate(); | |
System.out.println(t); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
var even = 0, odd = 0, i = 0; | |
i = 1; | |
while (i < 10) { | |
if (i % 2 == 2) { | |
even = even + 1; | |
} else { | |
odd = odd + 1; | |
} | |
i = i + 1; | |
} | |
return even + odd; | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
grammar Stone; | |
options { | |
output=AST; | |
ASTLabelType=CommonTree; | |
} | |
tokens { | |
UNARY_MINUS; | |
BLOCK; | |
SIMPLE; | |
} | |
@header { | |
import java.util.HashSet; | |
} | |
@members { | |
HashSet vars; | |
} | |
program | |
@init { | |
this.vars = new HashSet(); | |
} | |
: statement* EOF -> statement* | |
; | |
statement | |
: 'if' expr block ('else' block)? -> ^('if' expr block block?) | |
| 'while' expr block -> ^('while' expr block) | |
| simple NL -> ^(SIMPLE simple NL) | |
; | |
block | |
: '{' NL? statement* '}' NL? -> ^(BLOCK statement*) | |
; | |
simple | |
: expr | |
| assign | |
; | |
assign | |
: IDENTIFIER '=' simple | |
{ | |
vars.add($IDENTIFIER.text); | |
} | |
-> ^('=' IDENTIFIER simple) | |
; | |
expr | |
: (addExpr -> addExpr) ((op='=='|op='>'|op='<') rhs=addExpr -> ^($op $expr $rhs))* | |
; | |
addExpr | |
: (multExpr -> multExpr) ((op='+'|op='-') rhs=multExpr -> ^($op $addExpr $rhs))* | |
; | |
multExpr | |
: (factor -> factor) ((op='*'|op='/'|op='%') rhs=factor -> ^($op $multExpr $rhs))* | |
; | |
factor | |
: '-' primary -> ^(UNARY_MINUS primary) | |
| primary | |
; | |
primary | |
: '(' expr ')' -> expr | |
| NUMBER | |
| IDENTIFIER | |
| STRING | |
; | |
NUMBER | |
: '0'..'9'+ | |
; | |
STRING | |
: '"' ( ESC_SEQ | ~('\\'|'"') )* '"' | |
; | |
fragment | |
ESC_SEQ | |
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') | |
; | |
IDENTIFIER | |
: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* | |
; | |
NL | |
: 'r'? '\n' | |
; | |
WS | |
: ( ' ' | |
| '\t' | |
) {$channel=HIDDEN;} | |
; | |
COMMENT | |
: '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;} | |
| '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;} | |
; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
tree grammar StoneToJs; | |
options { | |
output=template; | |
tokenVocab=Stone; | |
ASTLabelType=CommonTree; | |
} | |
@header { | |
import java.util.Set; | |
} | |
program[Set vars] | |
: s+=statement* | |
{ | |
String text = ""; | |
for (int i = 0; i < $s.size(); i++) { | |
Object t = $s.get(i); | |
if (i == $s.size() - 1) { | |
text += "return "; | |
} | |
text += t.toString(); | |
} | |
$st=%program(vars={vars}, text={text}); | |
} | |
; | |
statement | |
: ^('if' expr thenBlock=block elseBlock=block?) -> if(cond={$expr.text}, thenBlock={$thenBlock.st}, elseBlock={$elseBlock.st}) | |
| ^('while' expr block) -> while(cond={$expr.text}, block={$block.st}) | |
| ^(SIMPLE simple NL) -> simple(text={$simple.st}) | |
; | |
block | |
: ^(BLOCK s+=statement*) | |
{ | |
String text = ""; | |
for (Object t: $s) { | |
text += t.toString(); | |
} | |
$st=%{text}; | |
} | |
; | |
simple | |
: expr { $st = %{$expr.text}; } | |
| assign { $st = $assign.st; } | |
; | |
assign | |
: ^('=' IDENTIFIER simple) -> assign(id={$IDENTIFIER.text}, expr={$simple.st}) | |
; | |
expr | |
: ^('==' expr expr) | |
| ^('>' expr expr) | |
| ^('<' expr expr) | |
| ^('+' expr expr) | |
| ^('-' expr expr) | |
| ^('*' expr expr) | |
| ^('/' expr expr) | |
| ^('%' expr expr) | |
| ^(UNARY_MINUS expr) | |
| NUMBER | |
| IDENTIFIER | |
| STRING | |
; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment