-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
99 changed files
with
7,899 additions
and
6 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<!-- ep20 POM --> | ||
<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> | ||
|
||
<parent> | ||
<groupId>org.teachfx</groupId> | ||
<artifactId>antlr4-parent</artifactId> | ||
<version>1.0.0</version> | ||
</parent> | ||
|
||
<artifactId>ep21</artifactId> | ||
<version>1.0.0</version> | ||
<properties> | ||
<!-- 这里为包含g4文件的文件夹--> | ||
<parser.g4.dir>src/main/java/org.teachfx.antlr4.ep21/parser</parser.g4.dir> | ||
<run.main.entry>org.teachfx.antlr4.ep21.Compiler</run.main.entry> | ||
</properties> | ||
<!-- 运行测试 --> | ||
<dependencies> | ||
|
||
<dependency> | ||
<groupId>org.jgrapht</groupId> | ||
<artifactId>jgrapht-core</artifactId> | ||
<version>1.5.2</version> | ||
<scope>compile</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
|
||
<!-- 添加ANTLR4插件 --> | ||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.antlr</groupId> | ||
<artifactId>antlr4-maven-plugin</artifactId> | ||
<version>4.11.0</version> | ||
<executions> | ||
<execution> | ||
<goals> | ||
<goal>antlr4</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
<configuration> | ||
<visitor>true</visitor> | ||
<!-- 指定 ANTLR4 生成代码的目录 --> | ||
<outputDirectory>${basedir}/src/main/java/org/teachfx/antlr4/ep21/parser</outputDirectory> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
<!-- 定义源码目录 --> | ||
<sourceDirectory>src/main/java</sourceDirectory> | ||
<resources> | ||
<resource> | ||
<directory>src/main/resources</directory> | ||
<targetPath>${project.build.directory}/classes</targetPath> | ||
<includes> | ||
<include>**/*.cymbol</include> <!-- 要包含的资源文件的模式 --> | ||
</includes> | ||
</resource> | ||
</resources> | ||
</build> | ||
|
||
|
||
</project> |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
grammar Cymbol; | ||
|
||
@header { | ||
package org.teachfx.antlr4.ep21.parser; | ||
} | ||
|
||
file : (functionDecl | varDecl)+ #compilationUnit ; | ||
|
||
varDecl | ||
: primaryType ID ('=' expr)? ';' | ||
; | ||
|
||
primaryType: 'float' | 'int' | 'void' | 'bool' | 'string' | 'object'; | ||
|
||
functionDecl | ||
: retType=primaryType funcName=ID '(' params=formalParameters? ')' blockDef=block // "void f(int x) {...}" | ||
; | ||
formalParameters | ||
: formalParameter (',' formalParameter)* | ||
; | ||
formalParameter | ||
: primaryType ID | ||
; | ||
|
||
block: '{' stmts=statetment* '}' ; // possibly empty statement block | ||
|
||
statetment: varDecl #statVarDecl | ||
| 'return' expr? ';' #statReturn | ||
| 'if' '(' cond=expr ')' then=statetment ('else' elseDo=statetment)? #stateCondition | ||
| 'while' '(' cond=expr ')' then=statetment #stateWhile | ||
| 'break' ';' #visitBreak | ||
| 'continue' ';' #visitContinue | ||
| expr '=' expr ';' #statAssign // assignment | ||
| expr ';' #exprStat // func call | ||
| block #statBlock | ||
; | ||
|
||
expr: callFunc=expr '(' ( expr (',' expr)* )? ')' #exprFuncCall // func call like f(), f(x), f(1,2) | ||
| o='-' expr #exprUnary // unary minus | ||
| o='!' expr #exprUnary // boolean not | ||
| expr o=('*'|'/') expr #exprBinary | ||
| expr o=('+'|'-') expr #exprBinary | ||
| expr o=('=='|'!='|'>'|'>='|'<'|'<=') expr #exprBinary | ||
| primary #exprPrimary | ||
| '(' expr ')' #exprGroup | ||
; | ||
|
||
primary: ID #primaryID // variable reference | ||
| INT #primaryINT | ||
| FLOAT #primaryFLOAT | ||
| CHAR #primaryCHAR | ||
| STRING #primarySTRING | ||
| BOOLEAN #primaryBOOL | ||
; | ||
|
||
ID : LETTER (LETTER | [0-9])* ; | ||
BOOLEAN: 'true' | 'false'; | ||
NULL : 'null'; | ||
|
||
fragment | ||
LETTER : [a-zA-Z] ; | ||
|
||
INT : [0-9]+ ; | ||
FLOAT : INT? '.' INT ; | ||
WS : [ \t\n\r]+ -> skip ; | ||
CHAR : '\'' . '\'' ; | ||
STRING: '"' ~( '"' | '\r' | '\n' )* '"'; | ||
|
||
SLCOMMENT | ||
: '//' .*? '\n' -> skip | ||
; | ||
|
||
COMMNET | ||
: '/*' .*? '*/' '\n' -> skip | ||
; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package org.teachfx.antlr4.ep21; | ||
|
||
import org.antlr.v4.runtime.CharStream; | ||
import org.antlr.v4.runtime.CharStreams; | ||
import org.antlr.v4.runtime.CommonTokenStream; | ||
import org.antlr.v4.runtime.tree.ParseTree; | ||
import org.teachfx.antlr4.ep21.ast.ASTNode; | ||
import org.teachfx.antlr4.ep21.parser.CymbolLexer; | ||
import org.teachfx.antlr4.ep21.parser.CymbolParser; | ||
import org.teachfx.antlr4.ep21.pass.ast.CymbolASTBuilder; | ||
import org.teachfx.antlr4.ep21.pass.cfg.ControlFlowAnalysis; | ||
import org.teachfx.antlr4.ep21.pass.codegen.CymbolAssembler; | ||
import org.teachfx.antlr4.ep21.pass.ir.CymbolIRBuilder; | ||
import org.teachfx.antlr4.ep21.pass.symtab.LocalDefine; | ||
|
||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.util.List; | ||
|
||
public class Compiler { | ||
|
||
public static void main(String[] args) throws IOException { | ||
String fileName = args.length > 0 ? args[0] : (new File("src/main/resources/t.cymbol")).getAbsolutePath(); | ||
|
||
InputStream is = System.in; | ||
if (fileName != null) is = new FileInputStream(fileName); | ||
CharStream charStream = CharStreams.fromStream(is); | ||
CymbolLexer lexer = new CymbolLexer(charStream); | ||
CommonTokenStream tokenStream = new CommonTokenStream(lexer); | ||
CymbolParser parser = new CymbolParser(tokenStream); | ||
ParseTree parseTree = parser.file(); | ||
CymbolASTBuilder astBuilder = new CymbolASTBuilder("t.cymbol"); | ||
ASTNode astRoot = parseTree.accept(astBuilder); | ||
astRoot.accept(new LocalDefine()); | ||
var irBuilder = new CymbolIRBuilder(); | ||
|
||
astRoot.accept(irBuilder); | ||
|
||
var dataFlowAnalysis = new ControlFlowAnalysis(); | ||
|
||
var assembler = new CymbolAssembler(); | ||
|
||
List.of(dataFlowAnalysis,assembler).forEach(irBuilder.root::accept); | ||
|
||
System.out.println(assembler.flushCode()); | ||
var url = Compiler.class.getClassLoader().getResource("t.vm"); | ||
System.out.println(">>>=" + new File(".").getAbsolutePath()); | ||
assembler.saveToFile("src/main/resources/t.vm"); | ||
assembler.saveToFile("../ep18/src/main/resources/t.vm"); | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
ep21/src/main/java/org/teachfx/antlr4/ep21/ast/ASTNode.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package org.teachfx.antlr4.ep21.ast; | ||
import org.antlr.v4.runtime.ParserRuleContext; | ||
import org.teachfx.antlr4.ep21.debugger.ast.Dumpable; | ||
import org.teachfx.antlr4.ep21.debugger.ast.Dumper; | ||
import org.teachfx.antlr4.ep21.parser.Location; | ||
|
||
import java.io.PrintStream; | ||
|
||
abstract public class ASTNode implements Dumpable { | ||
public ParserRuleContext ctx; | ||
public ParserRuleContext getCtx() { | ||
return ctx; | ||
} | ||
public Location getLocation() { | ||
if(ctx == null) { return null; } | ||
if(ctx.getStart() != ctx.getStop()) { | ||
return new Location(ctx.getStart().getLine(),ctx.getStart().getStartIndex(),ctx.stop.getLine(),ctx.stop.getStopIndex()); | ||
} | ||
|
||
return new Location(ctx.getStart().getLine(),ctx.getStart().getStartIndex(),ctx.stop.getLine(),ctx.stop.getStopIndex()); | ||
} | ||
|
||
public void accept(ASTVisitor visitor){} | ||
public void setCtx(ParserRuleContext ctx){ | ||
this.ctx = ctx; | ||
} | ||
|
||
public void dump() { | ||
dump(System.out); | ||
} | ||
|
||
public void dump(PrintStream s) { | ||
dump(new Dumper(s)); | ||
} | ||
|
||
public void dump(Dumper d) { | ||
d.printClass(this, getLocation()); | ||
_dump(d); | ||
} | ||
|
||
abstract protected void _dump(Dumper d); | ||
} | ||
|
102 changes: 102 additions & 0 deletions
102
ep21/src/main/java/org/teachfx/antlr4/ep21/ast/ASTVisitor.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package org.teachfx.antlr4.ep21.ast; | ||
|
||
import org.teachfx.antlr4.ep21.ast.decl.FuncDeclNode; | ||
import org.teachfx.antlr4.ep21.ast.decl.VarDeclNode; | ||
import org.teachfx.antlr4.ep21.ast.expr.*; | ||
import org.teachfx.antlr4.ep21.ast.stmt.*; | ||
import org.teachfx.antlr4.ep21.ast.type.TypeNode; | ||
|
||
public interface ASTVisitor<S,E> { | ||
/// Root Node | ||
S visit(CompileUnit rootNode); | ||
|
||
/// Decl | ||
S visit(VarDeclNode varDeclNode); | ||
|
||
S visit(FuncDeclNode funcDeclNode); | ||
|
||
S visit(VarDeclStmtNode varDeclStmtNode); | ||
|
||
/// Type | ||
E visit(TypeNode typeNode); | ||
|
||
// Expr | ||
default E visit(ExprNode node) { | ||
if (node instanceof BinaryExprNode) { | ||
return visit((BinaryExprNode) node); | ||
} else if (node instanceof IDExprNode) { | ||
return visit((IDExprNode) node); | ||
} else if (node instanceof BoolExprNode) { | ||
return visit((BoolExprNode) node); | ||
} else if (node instanceof CallFuncNode) { | ||
return visit((CallFuncNode) node); | ||
} else if (node instanceof IntExprNode) { | ||
return visit((IntExprNode) node); | ||
} else if (node instanceof FloatExprNode) { | ||
return visit((FloatExprNode) node); | ||
} else if (node instanceof NullExprNode) { | ||
return visit((NullExprNode) node); | ||
} else if (node instanceof StringExprNode) { | ||
return visit((StringExprNode) node); | ||
} else if (node instanceof UnaryExprNode) { | ||
return visit((UnaryExprNode) node); | ||
} | ||
return null; | ||
} | ||
E visit(BinaryExprNode binaryExprNode); | ||
|
||
E visit(IDExprNode idExprNode); | ||
|
||
/// literal value | ||
E visit(BoolExprNode boolExprNode); | ||
|
||
E visit(CallFuncNode callExprNode); | ||
|
||
E visit(IntExprNode intExprNode); | ||
|
||
E visit(FloatExprNode floatExprNode); | ||
|
||
E visit(NullExprNode nullExprNode); | ||
|
||
E visit(StringExprNode stringExprNode); | ||
|
||
E visit(UnaryExprNode unaryExprNode); | ||
|
||
/// Stmt | ||
S visit(IfStmtNode ifStmtNode); | ||
|
||
S visit(ExprStmtNode exprStmtNode); | ||
|
||
S visit(BlockStmtNode blockStmtNode); | ||
|
||
S visit(ReturnStmtNode returnStmtNode); | ||
|
||
S visit(WhileStmtNode whileStmtNode); | ||
|
||
S visit(AssignStmtNode assignStmtNode); | ||
|
||
S visit(BreakStmtNode breakStmtNode); | ||
|
||
S visit(ContinueStmtNode continueStmtNode); | ||
default S visit(StmtNode node) { | ||
if (node instanceof IfStmtNode) { | ||
return visit((IfStmtNode) node); | ||
} else if (node instanceof WhileStmtNode) { | ||
return visit((WhileStmtNode) node); | ||
} else if (node instanceof BlockStmtNode) { | ||
return visit((BlockStmtNode) node); | ||
} else if (node instanceof ExprStmtNode) { | ||
return visit((ExprStmtNode) node); | ||
} else if (node instanceof ReturnStmtNode) { | ||
return visit((ReturnStmtNode) node); | ||
} else if (node instanceof AssignStmtNode) { | ||
return visit((AssignStmtNode) node); | ||
} else if (node instanceof BreakStmtNode) { | ||
return visit((BreakStmtNode) node); | ||
} else if (node instanceof ContinueStmtNode) { | ||
return visit((ContinueStmtNode) node); | ||
} else { | ||
return visit((VarDeclStmtNode) node); | ||
} | ||
} | ||
} |
Oops, something went wrong.