Initial commit
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
#include "CodeGenVisitor.h"
|
||||
|
||||
antlrcpp::Any CodeGenVisitor::visitProg(ifccParser::ProgContext *ctx)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
std::cout<< ".globl _main\n" ;
|
||||
std::cout<< " _main: \n" ;
|
||||
#else
|
||||
std::cout<< ".globl main\n" ;
|
||||
std::cout<< " main: \n" ;
|
||||
#endif
|
||||
|
||||
this->visit( ctx->return_stmt() );
|
||||
|
||||
std::cout << " ret\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
antlrcpp::Any CodeGenVisitor::visitReturn_stmt(ifccParser::Return_stmtContext *ctx)
|
||||
{
|
||||
int retval = stoi(ctx->CONST()->getText());
|
||||
|
||||
std::cout << " movl $"<<retval<<", %eax\n" ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "antlr4-runtime.h"
|
||||
#include "generated/ifccBaseVisitor.h"
|
||||
|
||||
|
||||
class CodeGenVisitor : public ifccBaseVisitor {
|
||||
public:
|
||||
virtual antlrcpp::Any visitProg(ifccParser::ProgContext *ctx) override ;
|
||||
virtual antlrcpp::Any visitReturn_stmt(ifccParser::Return_stmtContext *ctx) override;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
# config.mk contains the paths to antlr4 etc.
|
||||
# Each student should have a config.mk corresponding to her system.
|
||||
# Examples are ubuntu.mk, DI.mk, fedora.mk
|
||||
# Then config.mk should be in the .gitignore of your project
|
||||
include config.mk
|
||||
|
||||
CC=g++
|
||||
CCFLAGS=-g -c -std=c++17 -I$(ANTLRINC) -Wno-attributes # -Wno-defaulted-function-deleted -Wno-unknown-warning-option
|
||||
LDFLAGS=-g
|
||||
|
||||
default: all
|
||||
all: ifcc
|
||||
|
||||
##########################################
|
||||
# link together all pieces of our compiler
|
||||
OBJECTS=build/ifccBaseVisitor.o \
|
||||
build/ifccLexer.o \
|
||||
build/ifccVisitor.o \
|
||||
build/ifccParser.o \
|
||||
build/main.o \
|
||||
build/CodeGenVisitor.o
|
||||
|
||||
ifcc: $(OBJECTS)
|
||||
@mkdir -p build
|
||||
$(CC) $(LDFLAGS) build/*.o $(ANTLRLIB) -o ifcc
|
||||
|
||||
##########################################
|
||||
# compile our hand-writen C++ code: main(), CodeGenVisitor, etc.
|
||||
build/%.o: %.cpp generated/ifccParser.cpp
|
||||
@mkdir -p build
|
||||
$(CC) $(CCFLAGS) -MMD -o $@ $<
|
||||
|
||||
##########################################
|
||||
# compile all the antlr-generated C++
|
||||
build/%.o: generated/%.cpp
|
||||
@mkdir -p build
|
||||
$(CC) $(CCFLAGS) -MMD -o $@ $<
|
||||
|
||||
# automagic dependency management: `gcc -MMD` generates all the .d files for us
|
||||
-include build/*.d
|
||||
build/%.d:
|
||||
|
||||
##########################################
|
||||
# generate the C++ implementation of our Lexer/Parser/Visitor
|
||||
generated/ifccLexer.cpp: generated/ifccParser.cpp
|
||||
generated/ifccVisitor.cpp: generated/ifccParser.cpp
|
||||
generated/ifccBaseVisitor.cpp: generated/ifccParser.cpp
|
||||
generated/ifccParser.cpp: ifcc.g4
|
||||
@mkdir -p generated
|
||||
java -jar $(ANTLRJAR) -visitor -no-listener -Dlanguage=Cpp -o generated ifcc.g4
|
||||
|
||||
# prevent automatic cleanup of "intermediate" files like ifccLexer.cpp etc
|
||||
.PRECIOUS: generated/ifcc%.cpp
|
||||
|
||||
##########################################
|
||||
# view the parse tree in a graphical window
|
||||
|
||||
# Usage: `make gui FILE=path/to/your/file.c`
|
||||
FILE ?= ../tests/testfiles/1_return42.c
|
||||
|
||||
gui:
|
||||
@mkdir -p generated build
|
||||
java -jar $(ANTLRJAR) -Dlanguage=Java -o generated ifcc.g4
|
||||
javac -cp $(ANTLRJAR) -d build generated/*.java
|
||||
java -cp $(ANTLRJAR):build org.antlr.v4.gui.TestRig ifcc axiom -gui $(FILE)
|
||||
|
||||
##########################################
|
||||
# delete all machine-generated files
|
||||
clean:
|
||||
rm -rf build generated
|
||||
rm -f ifcc
|
||||
@@ -0,0 +1,4 @@
|
||||
# these values work with the "install-antlr.sh" script provided for the PLD
|
||||
ANTLRJAR=../antlr/jar/antlr-4.9.2-complete.jar
|
||||
ANTLRINC=../antlr/include
|
||||
ANTLRLIB=../antlr/lib/libantlr4-runtime.a
|
||||
@@ -0,0 +1,3 @@
|
||||
ANTLRJAR=/home/$(USER)/antlr4-install/antlr-4.13.2-complete.jar
|
||||
ANTLRINC=/usr/local/include/antlr4-runtime/
|
||||
ANTLRLIB=/usr/local/lib/libantlr4-runtime.a
|
||||
@@ -0,0 +1,3 @@
|
||||
ANTLRJAR=/home/$(USER)/antlr4-install/antlr-4.13.2-complete.jar
|
||||
ANTLRINC=/usr/local/include/antlr4-runtime/
|
||||
ANTLRLIB=/usr/local/lib/libantlr4-runtime.a
|
||||
@@ -0,0 +1,13 @@
|
||||
grammar ifcc;
|
||||
|
||||
axiom : prog EOF ;
|
||||
|
||||
prog : 'int' 'main' '(' ')' '{' return_stmt '}' ;
|
||||
|
||||
return_stmt: RETURN CONST ';' ;
|
||||
|
||||
RETURN : 'return' ;
|
||||
CONST : [0-9]+ ;
|
||||
COMMENT : '/*' .*? '*/' -> skip ;
|
||||
DIRECTIVE : '#' .*? '\n' -> skip ;
|
||||
WS : [ \t\r\n] -> channel(HIDDEN);
|
||||
@@ -0,0 +1,56 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "antlr4-runtime.h"
|
||||
#include "generated/ifccLexer.h"
|
||||
#include "generated/ifccParser.h"
|
||||
#include "generated/ifccBaseVisitor.h"
|
||||
|
||||
#include "CodeGenVisitor.h"
|
||||
|
||||
using namespace antlr4;
|
||||
using namespace std;
|
||||
|
||||
int main(int argn, const char **argv)
|
||||
{
|
||||
stringstream in;
|
||||
if (argn==2)
|
||||
{
|
||||
ifstream lecture(argv[1]);
|
||||
if( !lecture.good() )
|
||||
{
|
||||
cerr<<"error: cannot read file: " << argv[1] << endl ;
|
||||
exit(1);
|
||||
}
|
||||
in << lecture.rdbuf();
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "usage: ifcc path/to/file.c" << endl ;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ANTLRInputStream input(in.str());
|
||||
|
||||
ifccLexer lexer(&input);
|
||||
CommonTokenStream tokens(&lexer);
|
||||
|
||||
tokens.fill();
|
||||
|
||||
ifccParser parser(&tokens);
|
||||
tree::ParseTree* tree = parser.axiom();
|
||||
|
||||
if(parser.getNumberOfSyntaxErrors() != 0)
|
||||
{
|
||||
cerr << "error: syntax error during parsing" << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
CodeGenVisitor v;
|
||||
v.visit(tree);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user