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;
/*===-------------------------------------------===*/
/* Lexer rules */
/*===-------------------------------------------===*/
INT: 'int';
RETURN: 'return';
ASSIGN: '=';
ADD: '+';
compUnit
: (funcDef | decl)+ EOF
;
LPAREN: '(';
RPAREN: ')';
LBRACE: '{';
RBRACE: '}';
SEMICOLON: ';';
decl
: constDecl
| varDecl
;
ID: [a-zA-Z_][a-zA-Z_0-9]*;
ILITERAL: [0-9]+;
constDecl
: Const bType constDef (Comma constDef)* Semi
;
WS: [ \t\r\n] -> skip;
LINECOMMENT: '//' ~[\r\n]* -> skip;
BLOCKCOMMENT: '/*' .*? '*/' -> skip;
bType
: Int
| Float
;
/*===-------------------------------------------===*/
/* Syntax rules */
/*===-------------------------------------------===*/
constDef
: Ident (L_BRAKT constExp R_BRAKT)* Assign constInitVal
;
compUnit
: funcDef EOF
constInitVal
: constExp
| L_BRACE (constInitVal (Comma constInitVal)*)? R_BRACE
;
decl
: btype varDef SEMICOLON
varDecl
: bType varDef (Comma varDef)* Semi
;
btype
: INT
funcDef
: funcType Ident L_PAREN (funcFParams)? R_PAREN block
;
varDef
: lValue (ASSIGN initValue)?
: Ident (L_BRAKT constExp R_BRAKT)* (Assign initVal)?
;
initValue
initVal
: exp
| L_BRACE (initVal (Comma initVal)*)? R_BRACE
;
funcDef
: funcType ID LPAREN RPAREN blockStmt
funcType
: Void
| Int
| Float
;
funcType
: INT
funcFParams
: funcFParam (Comma funcFParam)*
;
funcFParam
: bType Ident (L_BRAKT R_BRAKT (L_BRAKT exp R_BRAKT)*)?
;
blockStmt
: LBRACE blockItem* RBRACE
block
: L_BRACE (blockItem)* R_BRACE
;
blockItem
@ -71,28 +68,182 @@ blockItem
;
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
: RETURN exp SEMICOLON
exp
: addExp
;
exp
: LPAREN exp RPAREN # parenExp
| var # varExp
| number # numberExp
| exp ADD exp # additiveExp
cond
: lOrExp
;
var
: ID
lVar
: Ident (L_BRAKT exp R_BRAKT)*
;
lValue
: ID
primaryExp
: L_PAREN exp R_PAREN
| lVar
| 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