Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ make clean && make
cd ../../../
```

### 2. Запуск интеграционного теста
### 2. Запуск тестов в Docker
```bash
./integration_test.sh
bash ./docker_test.sh
```

### 3. Ручное тестирование
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ make clean && make
cd ../../../
```

#### Run Integration Test
#### Run Tests in Docker
```bash
# Run comprehensive integration test
./integration_test.sh
# Run the full test suite in Docker (native harness + Java tests)
bash ./docker_test.sh
```

### 4.2 Individual Component Testing
Expand Down
6 changes: 4 additions & 2 deletions compiler/src/main/cpp/parser/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ BISON_SRC = parser.y
LEX_SRC = lexer.l
AST_SRC = ast.cpp
SYMBOL_SRC = symbol.cpp
ANALYZER_SRC = analyzer.cpp
LEXER_SRC = lexer.cpp
JNI_SRC = jni_lexer.cpp

Expand All @@ -24,6 +25,7 @@ BISON_OBJ = parser.tab.o
LEX_OBJ = lex.yy.o
AST_OBJ = ast.o
SYMBOL_OBJ = symbol.o
ANALYZER_OBJ = analyzer.o
LEXER_OBJ = lexer.o
JNI_OBJ = jni_lexer.o

Expand All @@ -38,10 +40,10 @@ JNI_INCLUDES = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux -I.

all: $(JNI_H) $(TARGET) $(EXECUTABLE)

$(EXECUTABLE): $(BISON_OBJ) $(LEX_OBJ) $(AST_OBJ) $(SYMBOL_OBJ) $(LEXER_OBJ) $(JNI_OBJ)
$(EXECUTABLE): $(BISON_OBJ) $(LEX_OBJ) $(AST_OBJ) $(SYMBOL_OBJ) $(ANALYZER_OBJ) $(LEXER_OBJ) $(JNI_OBJ)
$(CXX) $(CXXFLAGS) -fPIC -o $@ $^ $(JNI_INCLUDES)

$(TARGET): $(BISON_OBJ) $(LEX_OBJ) $(AST_OBJ) $(SYMBOL_OBJ) $(LEXER_OBJ) $(JNI_OBJ)
$(TARGET): $(BISON_OBJ) $(LEX_OBJ) $(AST_OBJ) $(SYMBOL_OBJ) $(ANALYZER_OBJ) $(LEXER_OBJ) $(JNI_OBJ)
$(CXX) $(CXXFLAGS) -shared -fPIC -Wl,--no-as-needed -o $@ $^ $(JNI_INCLUDES)

$(BISON_C) $(BISON_H): $(BISON_SRC)
Expand Down
573 changes: 573 additions & 0 deletions compiler/src/main/cpp/parser/analyzer.cpp

Large diffs are not rendered by default.

49 changes: 49 additions & 0 deletions compiler/src/main/cpp/parser/analyzer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#ifndef ANALYZER_H
#define ANALYZER_H

#include <vector>
#include <string>
#include <unordered_set>
#include "ast.h"
#include "symbol.h"

extern SymbolTable* symbolTable;

class Analyzer {
public:
struct Result {
std::vector<std::string> errors;
std::vector<std::string> warnings;
size_t optimizationsApplied = 0;
bool success() const { return errors.empty(); }
};

explicit Analyzer(bool enableOptimizations = true)
: enableOpts(enableOptimizations) {}

Result analyze(ProgramNode* root);

private:
bool enableOpts;
Result result;

// Checks (no AST modification)
void runChecks(ProgramNode* root);
void checkNode(ASTNode* node);
void checkExpression(ExpressionNode* expr);
void checkStatement(StatementNode* stmt);
void checkRecordFieldAccess(FieldAccessNode* field);
void checkArrayIndex(ArrayAccessNode* arrAcc);
void checkRoutineCallTypes(const std::string& name, ASTNode* arguments);

// Optimizations (AST modification)
void runOptimizations(ProgramNode* root);
ExpressionNode* foldExpression(ExpressionNode* expr);
void simplifyInBody(BodyNode* body);
void simplifyInProgram(ProgramNode* program);
void removeUnusedDeclarations(ProgramNode* program);
void removeUnusedDeclarationsInBody(BodyNode* body, const std::unordered_set<std::string>& used);
void collectUsedVariables(ASTNode* node, std::unordered_set<std::string>& used);
};

#endif
Binary file added compiler/src/main/cpp/parser/analyzer.o
Binary file not shown.
Binary file modified compiler/src/main/cpp/parser/ast.o
Binary file not shown.
Binary file modified compiler/src/main/cpp/parser/jni_lexer.o
Binary file not shown.
Binary file modified compiler/src/main/cpp/parser/lex.yy.o
Binary file not shown.
2 changes: 1 addition & 1 deletion compiler/src/main/cpp/parser/lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extern int yylineno;

%%

[ \t] ; // ignore whitespace
[ \t\r]+ ; // ignore whitespace (include CR for Windows line endings)
\n { yylineno++; }

"var" { return TOK_VAR; }
Expand Down
Binary file modified compiler/src/main/cpp/parser/lexer.o
Binary file not shown.
Binary file modified compiler/src/main/cpp/parser/libparser.so
Binary file not shown.
Binary file modified compiler/src/main/cpp/parser/parser
Binary file not shown.
Binary file modified compiler/src/main/cpp/parser/parser.tab.o
Binary file not shown.
62 changes: 45 additions & 17 deletions compiler/src/main/cpp/parser/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "ast.h" // AST node definitions
#include "symbol.h" // Symbol table classes
#include "lexer.h" // Java lexer interface
#include "analyzer.h" // Semantic analyzer

// External lexer interface functions
extern int yylex();
Expand Down Expand Up @@ -477,6 +478,19 @@ public:
class WASMGenerator {
public:
void generate(ProgramNode* root) {
// Run analyzer before printing/generating code
Analyzer analyzer(/*enableOptimizations=*/true);
Analyzer::Result res = analyzer.analyze(root);
if (!res.errors.empty()) {
std::cout << "=== SEMANTIC ERRORS ===" << std::endl;
for (auto& e : res.errors) std::cout << "error: " << e << std::endl;
}
if (!res.warnings.empty()) {
std::cout << "=== SEMANTIC WARNINGS ===" << std::endl;
for (auto& w : res.warnings) std::cout << "warning: " << w << std::endl;
}
std::cout << "Optimizations applied: " << res.optimizationsApplied << std::endl;

ASTTreePrinter printer;
printer.printTree(root);
}
Expand Down Expand Up @@ -520,6 +534,7 @@ public:
%type <stmtNode> while_loop for_loop if_statement print_statement
%type <node> body range
%type <exprNode> expression relation simple factor summand primary
%type <exprNode> or_expr xor_expr and_expr
%type <exprNode> modifiable_primary routine_call
%type <node> expression_list argument_list

Expand Down Expand Up @@ -733,30 +748,43 @@ body: /* empty */ { $$ = new BodyNode(); symbolTable->enterScope(); }
}
;

expression: relation { $$ = $1; }
| expression TOK_AND relation { $$ = new BinaryOpNode(OpKind::AND, $1, $3); }
| expression TOK_OR relation { $$ = new BinaryOpNode(OpKind::OR, $1, $3); }
| expression TOK_XOR relation { $$ = new BinaryOpNode(OpKind::XOR, $1, $3); }
;
expression: or_expr { $$ = $1; }
;

// Boolean precedence: not > and > xor > or
or_expr: xor_expr { $$ = $1; }
| or_expr TOK_OR xor_expr { $$ = new BinaryOpNode(OpKind::OR, $1, $3); }
;

xor_expr: and_expr { $$ = $1; }
| xor_expr TOK_XOR and_expr { $$ = new BinaryOpNode(OpKind::XOR, $1, $3); }
;

and_expr: relation { $$ = $1; }
| and_expr TOK_AND relation { $$ = new BinaryOpNode(OpKind::AND, $1, $3); }
;

relation: simple { $$ = $1; }
| relation TOK_LESS simple { $$ = new BinaryOpNode(OpKind::LT, $1, $3); }
| relation TOK_LESS_EQUAL simple { $$ = new BinaryOpNode(OpKind::LE, $1, $3); }
| relation TOK_GREATER simple { $$ = new BinaryOpNode(OpKind::GT, $1, $3); }
| relation TOK_GREATER_EQUAL simple { $$ = new BinaryOpNode(OpKind::GE, $1, $3); }
| relation TOK_EQUAL simple { $$ = new BinaryOpNode(OpKind::EQ, $1, $3); }
| relation TOK_NOT_EQUAL simple { $$ = new BinaryOpNode(OpKind::NE, $1, $3); }
| relation TOK_LESS simple { $$ = new BinaryOpNode(OpKind::LT, $1, $3); }
| relation TOK_LESS_EQUAL simple { $$ = new BinaryOpNode(OpKind::LE, $1, $3); }
| relation TOK_GREATER simple { $$ = new BinaryOpNode(OpKind::GT, $1, $3); }
| relation TOK_GREATER_EQUAL simple { $$ = new BinaryOpNode(OpKind::GE, $1, $3); }
| relation TOK_EQUAL simple { $$ = new BinaryOpNode(OpKind::EQ, $1, $3); }
| relation TOK_NOT_EQUAL simple { $$ = new BinaryOpNode(OpKind::NE, $1, $3); }
;

// Adjusted precedence: multiplication/division/modulo bind tighter than addition/subtraction
// simple → handles addition/subtraction
simple: factor { $$ = $1; }
| simple TOK_MULTIPLY factor { $$ = new BinaryOpNode(OpKind::MUL, $1, $3); }
| simple TOK_DIVIDE factor { $$ = new BinaryOpNode(OpKind::DIV, $1, $3); }
| simple TOK_MODULO factor { $$ = new BinaryOpNode(OpKind::MOD, $1, $3); }
| simple TOK_PLUS factor { $$ = new BinaryOpNode(OpKind::PLUS, $1, $3); }
| simple TOK_MINUS factor { $$ = new BinaryOpNode(OpKind::MINUS, $1, $3); }
;

// factor → handles multiplication/division/modulo
factor: summand { $$ = $1; }
| factor TOK_PLUS summand { $$ = new BinaryOpNode(OpKind::PLUS, $1, $3); }
| factor TOK_MINUS summand { $$ = new BinaryOpNode(OpKind::MINUS, $1, $3); }
| factor TOK_MULTIPLY summand { $$ = new BinaryOpNode(OpKind::MUL, $1, $3); }
| factor TOK_DIVIDE summand { $$ = new BinaryOpNode(OpKind::DIV, $1, $3); }
| factor TOK_MODULO summand { $$ = new BinaryOpNode(OpKind::MOD, $1, $3); }
;

summand: primary { $$ = $1; }
Expand Down Expand Up @@ -830,7 +858,7 @@ int main(int argc, char** argv) {
// Parse input
int result = yyparse();

// Generate WASM code from AST (stub)
// Generate output (runs analyzer + prints AST)
if (result == 0 && astRoot && !hasParseError) {
WASMGenerator generator;
generator.generate(astRoot);
Expand Down
25 changes: 0 additions & 25 deletions compiler/src/main/cpp/parser/run_tests.sh

This file was deleted.

Binary file modified compiler/src/main/cpp/parser/symbol.o
Binary file not shown.
Empty file.
4 changes: 0 additions & 4 deletions compiler/src/main/cpp/parser/test1.out

This file was deleted.

Empty file.
4 changes: 0 additions & 4 deletions compiler/src/main/cpp/parser/test10.out

This file was deleted.

Empty file.
4 changes: 0 additions & 4 deletions compiler/src/main/cpp/parser/test2.out

This file was deleted.

Empty file.
4 changes: 0 additions & 4 deletions compiler/src/main/cpp/parser/test3.out

This file was deleted.

Empty file.
4 changes: 0 additions & 4 deletions compiler/src/main/cpp/parser/test4.out

This file was deleted.

Empty file.
4 changes: 0 additions & 4 deletions compiler/src/main/cpp/parser/test5.out

This file was deleted.

Empty file.
4 changes: 0 additions & 4 deletions compiler/src/main/cpp/parser/test6.out

This file was deleted.

Empty file.
4 changes: 0 additions & 4 deletions compiler/src/main/cpp/parser/test7.out

This file was deleted.

Empty file.
4 changes: 0 additions & 4 deletions compiler/src/main/cpp/parser/test8.out

This file was deleted.

Empty file.
4 changes: 0 additions & 4 deletions compiler/src/main/cpp/parser/test9.out

This file was deleted.

62 changes: 0 additions & 62 deletions compiler/src/main/cpp/parser/test_parser.cpp

This file was deleted.

7 changes: 0 additions & 7 deletions complex_test.i

This file was deleted.

Loading