Skip to content

Commit

Permalink
finish the parser for all programs in tests folder
Browse files Browse the repository at this point in the history
  • Loading branch information
ytsao committed Dec 1, 2024
1 parent ccffb94 commit fce9c96
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 36 deletions.
8 changes: 4 additions & 4 deletions abstract_interpreter/example/abstract_interpreter/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


int main(){
for (int i = 0; i < 1; ++i){
for (int i = 0; i < 20; ++i){
std::string filename = (i < 10 ? "0" : "") + std::to_string(i); // Add "0" prefix if i < 10
std::ifstream f("./tests/" + filename + ".c");
if (!f.is_open()){
Expand All @@ -19,11 +19,11 @@ int main(){
std::string input = buffer.str();
f.close();

std::cout << "Program content:\n" << input << std::endl;

// std::cout << "Program content:\n" << input << std::endl;
std::cout << "Program: " << filename << ".c" << std::endl;
AbstractInterpreterParser AIParser;
auto ast = AIParser.parse(input);
printAST(ast);
// printAST(ast);
}

return 0;
Expand Down
4 changes: 3 additions & 1 deletion abstract_interpreter/include/ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ std::ostream& operator<<(std::ostream& os, LogicOp lop){
return os;
}

enum class NodeType {VARIABLE, NUMBER, BINARY_OP, LOGIC_OP, DECLARATION, ASSIGNMENT, IFELSE, WHILELOOP, BLOCKCBODY};
enum class NodeType {VARIABLE, NUMBER, PRE_CON, BINARY_OP, LOGIC_OP, DECLARATION, ASSIGNMENT, IFELSE, WHILELOOP, BLOCKCBODY};
std::ostream& operator<<(std::ostream& os, NodeType type) {
switch (type) {
case NodeType::VARIABLE: os << "Variable"; break;
case NodeType::NUMBER: os << "Number"; break;
case NodeType::PRE_CON: os << "Pre-conditions"; break;
case NodeType::BINARY_OP: os << "Binary Operation"; break;
case NodeType::LOGIC_OP: os << "Logic Operation"; break;
case NodeType::DECLARATION: os << "Declaration"; break;
Expand Down Expand Up @@ -91,6 +92,7 @@ void printAST(const ASTNode& node, int depth = 0) {
switch (node.type) {
case NodeType::VARIABLE: std::cout << "Variable"; break;
case NodeType::NUMBER: std::cout << "Number"; break;
case NodeType::PRE_CON: std::cout << "Pre-condition"; break;
case NodeType::BINARY_OP: std::cout << "Binary Operator"; break;
case NodeType::LOGIC_OP: std::cout << "Logic Operator"; break;
case NodeType::DECLARATION: std::cout << "Declaration"; break;
Expand Down
74 changes: 66 additions & 8 deletions abstract_interpreter/include/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,25 @@ class AbstractInterpreterParser{
ASTNode parse(const std::string& input){
peg::parser parser(R"(
Program <- Statements*
Statements <- DeclareVar / Assignment / IfElse / WhileLoop / Block / Comment
Statements <- Block / PreCon / DeclareVar / Assignment / Increment / IfElse / WhileLoop / Comment
Integer <- < [+-]? [0-9]+ >
Identifier <- < [a-zA-Z_][a-zA-Z0-9_]* >
SeqOp <- '+' / '-'
PreOp <- '*' / '/'
LogicOp <- '<' / '>' / '<=' / '>=' / '==' / '!='
LogicOp <- '<=' / '>=' / '==' / '!=' / '<' / '>'
DeclareVar <- 'int' Identifier ('=' Integer / ',' Identifier)* ';'
PreCon <- '/*!npk' Identifier 'between' Integer 'and' Integer '*/'
Assignment <- Identifier '=' Expression ';'
Block <- ('void' 'main' '(' ')')? '{' Statements* '}'
Increment <- Identifier '++' ';'
Block <- ('void main' '(' ')')? '{' Statements* '}'
IfElse <- 'if' '(' Expression ')' (Block / Statements) ('else' (Block / Statements))?
WhileLoop <- 'while' '(' Expression ')' (Block / Statements)
Expression <- Term ((SeqOp / LogicOp) Term)*
Term <- Factor (PreOp Factor)*
Factor <- Integer / Identifier / '(' Expression ')'
Factor <- '-' Factor / Integer / Identifier / '(' Expression ')'
~Comment <- ('/*' / '//') [^\n\r]* [ \n\r\t]*
~Comment <- '/*' [^\n\r]* [ \n\r\t]*
%whitespace <- [ \n\r\t]*
)");
assert(static_cast<bool>(parser) == true);
Expand All @@ -48,12 +50,15 @@ class AbstractInterpreterParser{
parser["PreOp"] = [this](const SV& sv){return make_pre_op(sv);};
parser["LogicOp"] = [this](const SV& sv){return make_logic_op(sv);};
parser["DeclareVar"] = [this](const SV& sv){return make_decl_var(sv);};
parser["Assignment"] =[this](const SV& sv){return make_assign(sv);};
parser["PreCon"] = [this](const SV& sv){return make_pre_con(sv);};
parser["Assignment"] = [this](const SV& sv){return make_assign(sv);};
parser["Increment"] = [this](const SV& sv){return make_increment(sv);};
parser["Block"] = [this](const SV& sv){return make_block(sv);};
parser["IfElse"] = [this](const SV& sv){return make_ifelse(sv);};
parser["WhileLoop"] = [this](const SV& sv){return make_whileloop(sv);};
parser["Expression"] = [this](const SV& sv){return make_expr(sv);};
parser["Term"] = [this](const SV& sv){return make_term(sv);};
parser["Factor"] = [this](const SV& sv){return make_factor(sv);};
parser.set_logger([](size_t line, size_t col, const std::string& msg, const std::string &rule) {
std::cerr << line << ":" << col << ": " << msg << "\n";
});
Expand Down Expand Up @@ -97,6 +102,25 @@ class AbstractInterpreterParser{
return decl_node;
}

ASTNode make_pre_con(const SV& sv){
ASTNode pre_con_node(NodeType::PRE_CON, std::string("PreCon"));
ASTNode var(std::any_cast<ASTNode>(sv[0]));

// LB
ASTNode lb(NodeType::LOGIC_OP, std::string("<="));
lb.children.push_back(std::any_cast<ASTNode>(sv[1]));
lb.children.push_back(var);

// UB
ASTNode ub(NodeType::LOGIC_OP, std::string(">="));
ub.children.push_back(std::any_cast<ASTNode>(sv[2]));
ub.children.push_back(var);

pre_con_node.children.push_back(lb);
pre_con_node.children.push_back(ub);
return pre_con_node;
}

ASTNode make_seq_op(const SV& sv){
ASTNode op_node(NodeType::BINARY_OP);
std::string op = sv.token_to_string();
Expand Down Expand Up @@ -152,7 +176,20 @@ class AbstractInterpreterParser{
term.children.push_back(std::any_cast<ASTNode>(sv[2]));
return term;
}

}

ASTNode make_factor(const SV& sv){
if (sv.choice() == 0){
// for the case: x = -y;
// we're going to transform it into x = 0 - y;
ASTNode sign(NodeType::BINARY_OP, std::string("-"));
sign.children.push_back(ASTNode(0));
sign.children.push_back(std::any_cast<ASTNode>(sv[0]));
return sign;
}
else{
return std::any_cast<ASTNode>(sv[0]);
}
}

ASTNode make_assign(const SV& sv){
Expand All @@ -163,6 +200,20 @@ class AbstractInterpreterParser{
assign_node.children.push_back(expr);
return assign_node;
}

ASTNode make_increment(const SV& sv){
ASTNode increment_node(NodeType::ASSIGNMENT, std::string("="));

ASTNode var = std::any_cast<ASTNode>(sv[0]);
ASTNode plus_op(NodeType::BINARY_OP, std::string("+"));
plus_op.children.push_back(var);
plus_op.children.push_back(ASTNode(1));

increment_node.children.push_back(var);
increment_node.children.push_back(plus_op);

return increment_node;
}

ASTNode make_block(const SV& sv){
if (sv.size() == 1){
Expand All @@ -171,7 +222,14 @@ class AbstractInterpreterParser{
else{
ASTNode block_node(NodeType::BLOCKCBODY, std::string("BlockBody"));
for (size_t i = 0; i < sv.size(); ++i){
block_node.children.push_back(std::any_cast<ASTNode>(sv[i]));
try{
block_node.children.push_back(std::any_cast<ASTNode>(sv[i]));
}
catch(std::bad_any_cast){
// pre-condition in this version is comment, still is string;
// so, we cannot cast it as ASTNode;
continue;
}
}
return block_node;
}
Expand Down
12 changes: 1 addition & 11 deletions abstract_interpreter/tests/00.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
/*******************************************************************/
/* Cas d'etudes pour le projet du cours d'interpratation abstraite */
/* Ecrit par Olivier Bouissou ([email protected]) */
/* Le but de ces cas d'etudes est de vous permettre de tester */
/* votre projet sur des exemples de programmes contenant chacun */
/* une difficulte que vous devriez rencontrer. */
/*******************************************************************/
/* Caclul arithmetique 1. */
/* On cherche ici a tester les fonctions arithmetiques des domaines */
/* abstraits. */
/*******************************************************************/


int a, b, c, d, e, f;

Expand Down
12 changes: 0 additions & 12 deletions abstract_interpreter/tests/01.c
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
/*******************************************************************/
/* Cas d'etudes pour le projet du cours d'interpratation abstraite */
/* Ecrit par Olivier Bouissou ([email protected]) */
/* Le but de ces cas d'etudes est de vous permettre de tester */
/* votre projet sur des exemples de programmes contenant chacun */
/* une difficulte que vous devriez rencontrer. */
/*******************************************************************/
/* Caclul arithmetique 1. */
/* On cherche ici a tester les fonctions arithmetiques des domaines */
/* abstraits. */
/*******************************************************************/

int a, b, c, d, e;

void main() {
Expand Down

0 comments on commit fce9c96

Please sign in to comment.