Skip to content

Commit

Permalink
1. [PROJECT]::init ep21 from ep20.
Browse files Browse the repository at this point in the history
  • Loading branch information
whtoo committed Oct 16, 2023
1 parent 8573062 commit cffb504
Show file tree
Hide file tree
Showing 99 changed files with 7,899 additions and 6 deletions.
68 changes: 68 additions & 0 deletions ep21/pom.xml
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>
75 changes: 75 additions & 0 deletions ep21/src/main/antlr4/Cymbol.g4
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
;
53 changes: 53 additions & 0 deletions ep21/src/main/java/org/teachfx/antlr4/ep21/Compiler.java
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 ep21/src/main/java/org/teachfx/antlr4/ep21/ast/ASTNode.java
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 ep21/src/main/java/org/teachfx/antlr4/ep21/ast/ASTVisitor.java
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);
}
}
}
Loading

0 comments on commit cffb504

Please sign in to comment.