Compare commits

...

3 Commits

@ -0,0 +1,62 @@
#!/bin/bash
# 项目根目录
PROJECT_ROOT="/home/wu/nudt-compiler-cpp"
# 输出目录
TEST_RESULT_DIR="$PROJECT_ROOT/test/test_result"
# 编译g4文件生成C++代码
echo "=== 编译ANTLR grammar文件 ==="
java -jar "$PROJECT_ROOT/third_party/antlr-4.13.2-complete.jar" \
-Dlanguage=Cpp \
-visitor \
-no-listener \
-Xexact-output-dir \
-o "$PROJECT_ROOT/build/generated/antlr4" \
"$PROJECT_ROOT/src/antlr4/SysY.g4"
if [ $? -ne 0 ]; then
echo "错误ANTLR编译失败"
exit 1
fi
# 构建项目
echo "=== 构建项目 ==="
cmake -S "$PROJECT_ROOT" -B "$PROJECT_ROOT/build" \
-DCMAKE_BUILD_TYPE=Release \
-DCOMPILER_PARSE_ONLY=ON
if [ $? -ne 0 ]; then
echo "错误CMake配置失败"
exit 1
fi
cmake --build "$PROJECT_ROOT/build" -j "$(nproc)"
if [ $? -ne 0 ]; then
echo "错误:项目构建失败"
exit 1
fi
# 遍历测试用例
echo "=== 运行测试用例 ==="
find "$PROJECT_ROOT/test/test_case" -name "*.sy" | while read -r test_file; do
# 计算相对路径
relative_path=$(realpath --relative-to="$PROJECT_ROOT/test/test_case" "$test_file")
# 计算输出文件路径
output_file="$TEST_RESULT_DIR/$relative_path.tree"
# 创建输出目录
mkdir -p "$(dirname "$output_file")"
# 运行编译器
echo "处理:$relative_path"
"$PROJECT_ROOT/build/bin/compiler" --emit-parse-tree "$test_file" > "$output_file"
if [ $? -ne 0 ]; then
echo "警告:处理 $relative_path 时出错"
fi
done
echo "=== 测试完成 ==="
echo "结果保存在:$TEST_RESULT_DIR"

@ -1,68 +1,65 @@
// SysY 子集语法:支持形如
// int main() { int a = 1; int b = 2; return a + b; }
// 的最小返回表达式编译。
// 后续需要自行添加
grammar SysY; grammar SysY;
/*===-------------------------------------------===*/ compUnit
/* Lexer rules */ : (funcDef | decl)+ EOF
/*===-------------------------------------------===*/ ;
INT: 'int';
RETURN: 'return';
ASSIGN: '=';
ADD: '+';
LPAREN: '('; decl
RPAREN: ')'; : constDecl
LBRACE: '{'; | varDecl
RBRACE: '}'; ;
SEMICOLON: ';';
ID: [a-zA-Z_][a-zA-Z_0-9]*; constDecl
ILITERAL: [0-9]+; : Const bType constDef (Comma constDef)* Semi
;
WS: [ \t\r\n] -> skip; bType
LINECOMMENT: '//' ~[\r\n]* -> skip; : Int
BLOCKCOMMENT: '/*' .*? '*/' -> skip; | Float
;
/*===-------------------------------------------===*/ constDef
/* Syntax rules */ : Ident (L_BRAKT constExp R_BRAKT)* Assign constInitVal
/*===-------------------------------------------===*/ ;
compUnit constInitVal
: funcDef EOF : constExp
| L_BRACE (constInitVal (Comma constInitVal)*)? R_BRACE
; ;
decl varDecl
: btype varDef SEMICOLON : bType varDef (Comma varDef)* Semi
; ;
btype funcDef
: INT : funcType Ident L_PAREN (funcFParams)? R_PAREN block
; ;
varDef varDef
: lValue (ASSIGN initValue)? : Ident (L_BRAKT constExp R_BRAKT)* (Assign initVal)?
; ;
initValue initVal
: exp : exp
| L_BRACE (initVal (Comma initVal)*)? R_BRACE
; ;
funcDef funcType
: funcType ID LPAREN RPAREN blockStmt : Void
| Int
| Float
; ;
funcType funcFParams
: INT : funcFParam (Comma funcFParam)*
; ;
blockStmt funcFParam
: LBRACE blockItem* RBRACE : bType Ident (L_BRAKT R_BRAKT (L_BRAKT exp R_BRAKT)*)?
;
block
: L_BRACE (blockItem)* R_BRACE
; ;
blockItem blockItem
@ -71,28 +68,182 @@ blockItem
; ;
stmt stmt
: returnStmt : lVar Assign exp Semi
| (exp)? Semi
| block
| If L_PAREN cond R_PAREN stmt (Else stmt)?
| While L_PAREN cond R_PAREN stmt
| Break Semi
| Continue Semi
| Return (exp)? Semi
; ;
returnStmt exp
: RETURN exp SEMICOLON : addExp
; ;
exp cond
: LPAREN exp RPAREN # parenExp : lOrExp
| var # varExp
| number # numberExp
| exp ADD exp # additiveExp
; ;
var lVar
: ID : Ident (L_BRAKT exp R_BRAKT)*
; ;
lValue primaryExp
: ID : L_PAREN exp R_PAREN
| lVar
| number
; ;
number number
: ILITERAL : IntConst
| FloatConst
;
unaryExp
: primaryExp
| Ident L_PAREN (funcRParams)? R_PAREN
| unaryOp unaryExp
;
unaryOp : AddOp | '!';
funcRParams
: exp (Comma exp)*
;
mulExp
: unaryExp (MulOp unaryExp)*
;
addExp
: mulExp (AddOp mulExp)*
;
relExp
: addExp (RelOp addExp)*
;
eqExp
: relExp (EqOp relExp)*
;
lAndExp
: eqExp ('&&' eqExp)*
;
lOrExp
: lAndExp ('||' lAndExp)*
;
constExp
: addExp
;
Void : 'void';
Int : 'int';
Float : 'float';
Const : 'const';
If : 'if';
Else : 'else';
While : 'while';
Break : 'break';
Continue: 'continue';
Return : 'return';
Comma : ',';
Semi : ';';
L_PAREN : '(';
R_PAREN : ')';
L_BRAKT : '[';
R_BRAKT : ']';
L_BRACE : '{';
R_BRACE : '}';
Assign : '=';
MulOp : '*' | '/' | '%';
AddOp : '+' | '-';
RelOp : '<' | '>' | '<=' | '>=';
EqOp : '==' | '!=';
Ident
: [a-zA-Z_][a-zA-Z_0-9]*
;
IntConst
: DecInt
| OctInt
| HexInt
;
fragment DecInt
: NonZeroD Digit*
;
fragment OctInt
: '0' OctDigit*
;
fragment HexInt
: HexPre HexDigit+
;
FloatConst
: DecFloat
| HexFloat
;
fragment DecFloat
: Fraction Exponent?
| DiSeq Exponent
;
fragment HexFloat
: HexPre (HexFraction | HexDiSeq) BiExponent
;
fragment Fraction
: DiSeq? '.' DiSeq
| DiSeq '.'
;
fragment Exponent
: [eE] ('+' | '-')? DiSeq
;
fragment DiSeq
: Digit+
;
fragment HexFraction
: HexDiSeq? '.' HexDiSeq
| HexDiSeq '.'
;
fragment BiExponent
: [pP] ('+' | '-')? DiSeq
;
fragment HexDiSeq
: HexDigit+
;
fragment NonZeroD: [1-9];
fragment Digit : [0-9];
fragment OctDigit: [0-7];
fragment HexPre : '0' [xX];
fragment HexDigit: [0-9A-Fa-f];
WS
: [ \t\r\n]+ -> skip
;
COMMENT
: '//' ~[\r\n]* -> skip
;
BLOCK_COMMENT
: '/*' .*? '*/' -> skip
; ;

Loading…
Cancel
Save