feat(ast): 添加AST定义和dump工具头文件

新增libs/ast模块的基础定义文件,包括:
- AST节点类型枚举定义,涵盖声明、语句、表达式、类型等各类节点
- AST操作符枚举,定义所有二元、一元、逻辑、算术等操作符
- AST节点结构体定义,包含表达式、语句、声明、类型等具体实现
- AST dump工具接口,支持树形结构输出和颜色显示
- 语义分析回调函数类型定义,为后续语义分析提供基础
This commit is contained in:
zzy
2026-01-28 15:44:59 +08:00
parent e1cd8c5206
commit 79ee7a657a
13 changed files with 4181 additions and 0 deletions

View File

@@ -0,0 +1,250 @@
#include <parser.h>
/*
A.2.2 Declarations
(6.7) declaration:
declaration-specifiers init-declarator-list(opt) ;
(6.7) declaration-specifiers:
storage-class-specifier declaration-specifiers(opt)
type-specifier declaration-specifiers(opt)
type-qualifier declaration-specifiers(opt)
function-specifier declaration-specifiers(opt)
(6.7) init-declarator-list:
init-declarator
init-declarator-list , init-declarator
(6.7) init-declarator:
declarator
declarator = initializer
(6.7.1) storage-class-specifier:
typedef
extern
static
auto
register
(6.7.2) type-specifier:
void
char
short
int
long
float
double
signed
unsigned
_Bool
_Complex
struct-or-union-specifier
enum-specifier
typedef-name
(6.7.2.1) struct-or-union-specifier:
struct-or-union identifier(opt) { struct-declaration-list }
struct-or-union identifier
(6.7.2.1) struct-or-union:
struct
union
(6.7.2.1) struct-declaration-list:
struct-declaration
struct-declaration-list struct-declaration
(6.7.2.1) struct-declaration:
specifier-qualifier-list struct-declarator-list ;
(6.7.2.1) specifier-qualifier-list:
type-specifier specifier-qualifier-list(opt)
type-qualifier specifier-qualifier-list(opt)
(6.7.2.1) struct-declarator-list:
struct-declarator
struct-declarator-list , struct-declarator
(6.7.2.1) struct-declarator:
declarator
declarator(opt) : constant-expression
(6.7.2.2) enum-specifier:
enum identifier(opt) { enumerator-list }
enum identifier(opt) { enumerator-list ,}
enum identifier
(6.7.2.2) enumerator-list:
enumerator
enumerator-list , enumerator
(6.7.2.2) enumerator:
enumeration-constant
enumeration-constant = constant-expression
(6.7.3) type-qualifier:
const
restrict
volatile
(6.7.4) function-specifier:
inline
(6.7.5) declarator:
pointer(opt) direct-declarator
(6.7.5) direct-declarator:
identifier
( declarator )
direct-declarator [ type-qualifier-list(opt)
assignment-expression(opt) ]
direct-declarator [ static type-qualifier-list(opt)
assignment-expression ]
direct-declarator [ type-qualifier-list static
assignment-expression ]
direct-declarator [ type-qualifier-list(opt) *]
direct-declarator ( parameter-type-list )
direct-declarator ( identifier-list(opt) )
(6.7.5) pointer:
* type-qualifier-list(opt)
* type-qualifier-list(opt) pointer
(6.7.5) type-qualifier-list:
type-qualifier
type-qualifier-list type-qualifier
(6.7.5) parameter-type-list:
parameter-list
parameter-list , ...
(6.7.5) parameter-list:
parameter-declaration
parameter-list , parameter-declaration
(6.7.5) parameter-declaration:
declaration-specifiers declarator
declaration-specifiers abstract-declarator(opt)
(6.7.5) identifier-list:
identifier
identifier-list , identifier
(6.7.6) type-name:
specifier-qualifier-list abstract-declarator(opt)
(6.7.6) abstract-declarator:
pointer
pointer(opt) direct-abstract-declarator
(6.7.6) direct-abstract-declarator:
( abstract-declarator )
direct-abstract-declarator(opt) [ type-qualifier-list (opt)
assignment-expression(opt) ]
direct-abstract-declarator(opt) [static type-qualifier-list(opt)
assignment-expression ]
direct-abstract-declaratoropt [ type-qualifier-list static
assignment-expression ]
direct-abstract-declarator(opt) [ * ]
direct-abstract-declarator(opt) ( parameter-type-list(opt) )
(6.7.7) typedef-name:
identifier
(6.7.8) initializer:
assignment-expression
{ initializer-list }
{ initializer-list , }
(6.7.8) initializer-list:
designation(opt) initializer
initializer-list , designation(opt) initializer
(6.7.8) designation:
designator-list =
(6.7.8) designator-list:
designator
designator-list designator
(6.7.8) designator:
[ constant-expression ]
. identifier
A.2.4 External definitions
(6.9) translation-unit:
external-declaration
translation-unit external-declaration
(6.9) external-declaration:
function-definition
declaration
(6.9.1) function-definition:
declaration-specifiers declarator declaration-list(opt)
compound-statement
(6.9.1) declaration-list:
declaration
declaration-list declaration
*/
scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
/**
* ISO/IEC 9899:TC3
* 6.7 Declarations
* Syntax
*
* declaration:
* declaration-specifiers init-declarator-list(opt) ;
* declaration-specifiers:
* storage-class-specifier declaration-specifiers(opt)
* type-specifier declaration-specifiers(opt)
* type-qualifier declaration-specifiers(opt)
* function-specifier declaration-specifiers(opt)
* init-declarator-list:
* init-declarator
* init-declarator-list , init-declarator
* init-declarator:
* declarator
* declarator = initializer
*/
if (!scc_parse_is_declaration_start(parser, 0)) {
return null;
}
scc_ast_type_t *type = scc_parse_type(parser);
if (type == null) {
LOG_ERROR("Failed to parse type");
return null;
}
const scc_lexer_tok_t *tok = scc_lexer_stream_current(parser->lex_stream);
if (!scc_lexer_tok_match(tok, SCC_TOK_IDENT)) {
LOG_ERROR("Expected identifier, got %s", scc_get_tok_name(tok->type));
return null;
}
scc_lexer_stream_consume(parser->lex_stream);
scc_ast_decl_t *decl = scc_malloc(sizeof(scc_ast_decl_t));
/*
(6.7.5) declarator:
pointeropt direct-declarator
(6.7.5) direct-declarator:
identifier
( declarator )
direct-declarator [ type-qualifier-listopt assignment-expressionopt ]
direct-declarator [static type-qualifier-listopt assignment-expression ]
direct-declarator [ type-qualifier-list static assignment-expression ]
direct-declarator [ type-qualifier-listopt *]
direct-declarator ( parameter-type-list )
direct-declarator ( identifier-listopt )
*/
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_L_PAREN)) {
// TODO
if (scc_parse_consume_if(parser->lex_stream, SCC_TOK_SEMICOLON)) {
decl->base.type = SCC_AST_DECL_VAR;
decl->var.type = type;
decl->var.name = tok->value.cstr.data;
decl->var.init = null;
return decl;
} else if (scc_parse_consume_if(parser->lex_stream, SCC_TOK_ASSIGN)) {
decl->base.type = SCC_AST_DECL_VAR;
decl->var.type = type;
decl->var.name = tok->value.cstr.data;
decl->var.init = scc_parse_expression(parser);
return decl;
}
return null;
}
// function decl
decl->base.type = SCC_AST_DECL_FUNC;
decl->func.name = tok->value.cstr.data;
decl->func.type = scc_malloc(sizeof(scc_ast_type_t));
decl->func.type->base.type = SCC_AST_TYPE_FUNCTION;
scc_vec_init(decl->func.type->function.param_types);
decl->func.type->function.return_type = type;
// TODO
decl->func.type->function.is_variadic = false;
// TODO param type
scc_parse_consume_if(parser->lex_stream, SCC_TOK_VOID);
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_R_PAREN)) {
return null;
}
if (!scc_parse_is(parser->lex_stream, SCC_TOK_L_BRACE)) {
return null;
}
decl->func.body = scc_parse_statement(parser);
Assert(decl->func.type != null);
Assert(decl->func.type->base.type == SCC_AST_TYPE_FUNCTION);
Assert(decl->func.body != null);
Assert(decl->func.body->base.type == SCC_AST_STMT_COMPOUND);
return decl;
}

View File

@@ -0,0 +1,918 @@
/**
* @file parse_expr.c
* @author your name (you@domain.com)
* @brief Pratt Parser表达式解析器
* @version 0.1
* @date 2026-01-09
*
* @copyright Copyright (c) 2026
*
*/
#include <parser.h>
/*
A.2.1 Expressions
(6.5.1)
primary-expression:
identifier
constant
string-literal
( expression )
(6.5.2)
postfix-expression:
primary-expression
postfix-expression [ expression ]
postfix-expression ( argument-expression-list(opt) )
postfix-expression . identifier
postfix-expression -> identifier
postfix-expression ++
postfix-expression --
( type-name ) { initializer-list }
( type-name ) { initializer-list , }
(6.5.2)
argument-expression-list:
assignment-expression
argument-expression-list , assignment-expression
(6.5.3)
unary-expression:
postfix-expression
++ unary-expression
-- unary-expression
unary-operator cast-expression
sizeof unary-expression
sizeof ( type-name )
(6.5.3)
unary-operator: one of
& * + - ~ !
(6.5.4)
cast-expression:
unary-expression
( type-name ) cast-expression
(6.5.5)
multiplicative-expression:
cast-expression
multiplicative-expression * cast-expression
multiplicative-expression / cast-expression
multiplicative-expression % cast-expression
(6.5.6)
additive-expression:
multiplicative-expression
additive-expression + multiplicative-expression
additive-expression - multiplicative-expression
(6.5.7)
shift-expression:
additive-expression
shift-expression << additive-expression
shift-expression >> additive-expression
(6.5.8)
relational-expression:
shift-expression
relational-expression < shift-expression
relational-expression > shift-expression
relational-expression <= shift-expression
relational-expression >= shift-expression
(6.5.9)
equality-expression:
relational-expression
equality-expression == relational-expression
equality-expression != relational-expression
(6.5.10)
AND-expression:
equality-expression
AND-expression & equality-expression
(6.5.11)
exclusive-OR-expression:
AND-expression
exclusive-OR-expression ^ AND-expression
(6.5.12)
inclusive-OR-expression:
exclusive-OR-expression
inclusive-OR-expression | exclusive-OR-expression
(6.5.13)
logical-AND-expression:
inclusive-OR-expression
logical-AND-expression && inclusive-OR-expression
(6.5.14)
logical-OR-expression:
logical-AND-expression
logical-OR-expression || logical-AND-expression
(6.5.15)
conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
(6.5.16)
assignment-expression:
conditional-expression
unary-expression assignment-operator assignment-expression
(6.5.16)
assignment-operator: one of
= *= /= %= +=-= <<= >>= &= ^= |=
(6.5.17)
expression:
assignment-expression
expression , assignment-expression
(6.6)
constant-expression:
conditional-expression
*/
/**
* @brief 从token映射到AST操作符
* @param tok_type 词法token类型
* @param is_unary 是否为一元操作符上下文
* @return AST操作符类型
*/
static scc_ast_expr_op_t scc_ast_token_to_operator(scc_tok_type_t tok_type,
cbool is_unary) {
switch (tok_type) {
/* 赋值操作符 */
case SCC_TOK_ASSIGN:
return SCC_AST_OP_ASSIGN;
case SCC_TOK_ASSIGN_ADD:
return SCC_AST_OP_ASSIGN_ADD;
case SCC_TOK_ASSIGN_SUB:
return SCC_AST_OP_ASSIGN_SUB;
case SCC_TOK_ASSIGN_MUL:
return SCC_AST_OP_ASSIGN_MUL;
case SCC_TOK_ASSIGN_DIV:
return SCC_AST_OP_ASSIGN_DIV;
case SCC_TOK_ASSIGN_MOD:
return SCC_AST_OP_ASSIGN_MOD;
case SCC_TOK_ASSIGN_AND:
return SCC_AST_OP_ASSIGN_AND;
case SCC_TOK_ASSIGN_XOR:
return SCC_AST_OP_ASSIGN_XOR;
case SCC_TOK_ASSIGN_OR:
return SCC_AST_OP_ASSIGN_OR;
case SCC_TOK_ASSIGN_L_SH:
return SCC_AST_OP_ASSIGN_LSHIFT;
case SCC_TOK_ASSIGN_R_SH:
return SCC_AST_OP_ASSIGN_RSHIFT;
/* 逻辑操作符 */
case SCC_TOK_OR_OR:
return SCC_AST_OP_LOGICAL_OR;
case SCC_TOK_AND_AND:
return SCC_AST_OP_LOGICAL_AND;
/* 位操作符 */
case SCC_TOK_OR:
return SCC_AST_OP_BITWISE_OR;
case SCC_TOK_XOR:
return SCC_AST_OP_BITWISE_XOR;
case SCC_TOK_AND:
return is_unary ? SCC_AST_OP_ADDRESS_OF : SCC_AST_OP_BITWISE_AND;
/* 相等性操作符 */
case SCC_TOK_EQ:
return SCC_AST_OP_EQUAL;
case SCC_TOK_NEQ:
return SCC_AST_OP_NOT_EQUAL;
/* 关系操作符 */
case SCC_TOK_LT:
return SCC_AST_OP_LESS;
case SCC_TOK_GT:
return SCC_AST_OP_GREATER;
case SCC_TOK_LE:
return SCC_AST_OP_LESS_EQUAL;
case SCC_TOK_GE:
return SCC_AST_OP_GREATER_EQUAL;
/* 移位操作符 */
case SCC_TOK_L_SH:
return SCC_AST_OP_LEFT_SHIFT;
case SCC_TOK_R_SH:
return SCC_AST_OP_RIGHT_SHIFT;
/* 算术操作符 */
case SCC_TOK_ADD:
return is_unary ? SCC_AST_OP_UNARY_PLUS : SCC_AST_OP_ADD;
case SCC_TOK_SUB:
return is_unary ? SCC_AST_OP_UNARY_MINUS : SCC_AST_OP_SUB;
case SCC_TOK_MUL:
return is_unary ? SCC_AST_OP_INDIRECTION : SCC_AST_OP_MUL;
case SCC_TOK_DIV:
return SCC_AST_OP_DIV;
case SCC_TOK_MOD:
return SCC_AST_OP_MOD;
/* 一元操作符 */
case SCC_TOK_NOT:
return SCC_AST_OP_LOGICAL_NOT;
case SCC_TOK_BIT_NOT:
return SCC_AST_OP_BITWISE_NOT;
case SCC_TOK_ADD_ADD:
return is_unary ? SCC_AST_OP_PREFIX_INCREMENT
: SCC_AST_OP_POSTFIX_INCREMENT;
case SCC_TOK_SUB_SUB:
return is_unary ? SCC_AST_OP_PREFIX_DECREMENT
: SCC_AST_OP_POSTFIX_DECREMENT;
default:
return SCC_AST_OP_NONE;
}
}
/**
* @brief 运算符优先级定义
*/
typedef enum {
PREC_NONE = 0, // 无优先级
PREC_COMMA = 1, // ,
PREC_ASSIGNMENT = 2, // = += -= *= /= %= &= ^= |= <<= >>=
PREC_CONDITIONAL = 3, // ?:
PREC_LOGICAL_OR = 4, // ||
PREC_LOGICAL_AND = 5, // &&
PREC_BITWISE_OR = 6, // |
PREC_BITWISE_XOR = 7, // ^
PREC_BITWISE_AND = 8, // &
PREC_EQUALITY = 9, // == !=
PREC_RELATIONAL = 10, // < > <= >=
PREC_SHIFT = 11, // << >>
PREC_ADDITIVE = 12, // + -
PREC_MULTIPLICATIVE = 13, // * / %
PREC_CAST = 14, // 类型转换
PREC_UNARY = 15, // ++ -- + - * & ~ ! sizeof
PREC_POSTFIX = 16, // [] () . -> ++ --
PREC_PRIMARY = 17, // 最高优先级
} scc_precedence_t;
/**
* @brief 获取二元运算符优先级
*/
static scc_precedence_t get_binary_precedence(scc_tok_type_t op) {
switch (op) {
case SCC_TOK_COMMA:
return PREC_COMMA;
case SCC_TOK_ASSIGN:
case SCC_TOK_ASSIGN_ADD:
case SCC_TOK_ASSIGN_SUB:
case SCC_TOK_ASSIGN_MUL:
case SCC_TOK_ASSIGN_DIV:
case SCC_TOK_ASSIGN_MOD:
case SCC_TOK_ASSIGN_AND:
case SCC_TOK_ASSIGN_XOR:
case SCC_TOK_ASSIGN_OR:
case SCC_TOK_ASSIGN_L_SH:
case SCC_TOK_ASSIGN_R_SH:
return PREC_ASSIGNMENT;
case SCC_TOK_COND:
return PREC_CONDITIONAL;
case SCC_TOK_OR_OR:
return PREC_LOGICAL_OR;
case SCC_TOK_AND_AND:
return PREC_LOGICAL_AND;
case SCC_TOK_OR:
return PREC_BITWISE_OR;
case SCC_TOK_XOR:
return PREC_BITWISE_XOR;
case SCC_TOK_AND:
return PREC_BITWISE_AND;
case SCC_TOK_EQ:
case SCC_TOK_NEQ:
return PREC_EQUALITY;
case SCC_TOK_LT:
case SCC_TOK_GT:
case SCC_TOK_LE:
case SCC_TOK_GE:
return PREC_RELATIONAL;
case SCC_TOK_L_SH:
case SCC_TOK_R_SH:
return PREC_SHIFT;
case SCC_TOK_ADD:
case SCC_TOK_SUB:
return PREC_ADDITIVE;
case SCC_TOK_MUL:
case SCC_TOK_DIV:
case SCC_TOK_MOD:
return PREC_MULTIPLICATIVE;
default:
return PREC_NONE;
}
}
/**
* @brief 检查是否是赋值运算符
*/
static cbool is_assignment_operator(scc_tok_type_t op) {
switch (op) {
case SCC_TOK_ASSIGN:
case SCC_TOK_ASSIGN_ADD:
case SCC_TOK_ASSIGN_SUB:
case SCC_TOK_ASSIGN_MUL:
case SCC_TOK_ASSIGN_DIV:
case SCC_TOK_ASSIGN_MOD:
case SCC_TOK_ASSIGN_AND:
case SCC_TOK_ASSIGN_XOR:
case SCC_TOK_ASSIGN_OR:
case SCC_TOK_ASSIGN_L_SH:
case SCC_TOK_ASSIGN_R_SH:
return true;
default:
return false;
}
}
/**
* @brief 检查是否是二元运算符
*/
static cbool is_binary_operator(scc_tok_type_t op) {
return get_binary_precedence(op) != PREC_NONE;
}
static inline scc_ast_expr_t *expr_create(scc_parser_t *parser,
scc_ast_node_type_t type) {
scc_ast_expr_t *expr = (scc_ast_expr_t *)scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
expr->base.type = type;
expr->base.loc = scc_pos_create();
return expr;
}
/**
* @brief 解析基本表达式
*
* (6.5.1) primary-expression:
* identifier
* constant
* string-literal
* ( expression )
*/
static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
const scc_lexer_tok_t *tok = scc_lexer_stream_current(parser->lex_stream);
switch (tok->type) {
case SCC_TOK_IDENT: {
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_IDENTIFIER);
if (!expr)
return null;
expr->identifier.name = tok->value.cstr.data;
scc_lexer_stream_consume(parser->lex_stream);
// 调用语义回调
if (parser->sema_callbacks.on_expr) {
parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
expr->base.type, expr);
}
return expr;
}
case SCC_TOK_INT_LITERAL:
case SCC_TOK_FLOAT_LITERAL:
case SCC_TOK_CHAR_LITERAL: {
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_INT_LITERAL);
if (!expr)
return null;
expr->literal.value = tok->value;
scc_lexer_stream_consume(parser->lex_stream);
if (parser->sema_callbacks.on_expr) {
parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
expr->base.type, expr);
}
return expr;
}
case SCC_TOK_STRING_LITERAL: {
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_STRING_LITERAL);
if (!expr)
return null;
expr->literal.value = tok->value;
scc_lexer_stream_consume(parser->lex_stream);
if (parser->sema_callbacks.on_expr) {
parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
expr->base.type, expr);
}
return expr;
}
case SCC_TOK_L_PAREN: {
TODO();
// // 保存当前位置,用于区分类型转换和括号表达式
// usize save_pos = parser->lex_stream->curr_pos;
// // 跳过 '('
// scc_lexer_stream_consume(parser->lex_stream);
// // 尝试解析类型转换
// if (parser_is_type_start(parser)) {
// scc_ast_type_t *type = scc_parse_type_name(parser);
// if (type && parser_consume_if(parser, SCC_TOK_R_PAREN)) {
// // 成功解析类型转换
// scc_ast_expr_t *cast = expr_create(parser,
// SCC_AST_EXPR_CAST); if (!cast) {
// scc_free(type);
// return null;
// }
// cast->cast.type = type;
// cast->cast.expr = scc_parse_expression(parser, 0); //
// 递归解析
// if (parser->sema_callbacks.on_expr) {
// parser->sema_callbacks.on_expr(
// parser->sema_callbacks.context, cast->node_type,
// cast);
// }
// return cast;
// }
// // 解析失败,清理
// if (type)
// scc_free(type);
// }
// // 不是类型转换,恢复为括号表达式
// parser->lex_stream->curr_pos = save_pos;
// scc_lexer_stream_consume(parser->lex_stream); // 跳过 '('
// scc_ast_expr_t *expr = scc_parse_expression(parser, 0);
// if (!expr) {
// return null;
// }
// if (!parser_consume_if(parser, SCC_TOK_R_PAREN)) {
// PARSER_ERROR(parser, "expected ')' after expression");
// scc_free(expr);
// return null;
// }
// 括号表达式不需要特殊节点,直接返回内部表达式
// return expr;
}
default:
LOG_ERROR("expected primary expression, got %s",
scc_get_tok_name(tok->type));
return null;
}
}
/**
* @brief 解析后缀表达式
*
* (6.5.2) postfix-expression:
* primary-expression
* postfix-expression [ expression ]
* postfix-expression ( argument-expression-list(opt) )
* postfix-expression . identifier
* postfix-expression -> identifier
* postfix-expression ++
* postfix-expression --
* ( type-name ) { initializer-list }
* ( type-name ) { initializer-list , }
*/
static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser,
scc_ast_expr_t *lhs) {
scc_ast_expr_t *expr = lhs;
while (true) {
const scc_lexer_tok_t *tok =
scc_lexer_stream_current(parser->lex_stream);
switch (tok->type) {
case SCC_TOK_L_BRACKET: { // 数组下标
scc_lexer_stream_consume(parser->lex_stream); // 跳过 '['
scc_ast_expr_t *subscript =
expr_create(parser, SCC_AST_EXPR_ARRAY_SUBSCRIPT);
if (!subscript) {
scc_free(expr);
return null;
}
subscript->subscript.array = expr;
subscript->subscript.index = scc_parse_expression(parser);
if (!subscript->subscript.index) {
scc_free(subscript);
return null;
}
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_R_BRACKET)) {
LOG_ERROR("expected ']' after array index");
scc_free(subscript);
return null;
}
expr = subscript;
break;
}
case SCC_TOK_L_PAREN: { // 函数调用
scc_lexer_stream_consume(parser->lex_stream); // 跳过 '('
scc_ast_expr_t *call = expr_create(parser, SCC_AST_EXPR_CALL);
if (!call) {
scc_free(expr);
return null;
}
call->call.callee = expr;
scc_vec_init(call->call.args);
// 解析参数列表
if (!scc_parse_is(parser->lex_stream, SCC_TOK_R_PAREN)) {
do {
scc_ast_expr_t *arg = scc_parse_expression(parser);
if (!arg) {
// 清理已解析的参数
scc_vec_foreach(call->call.args, i) {
scc_free(scc_vec_at(call->call.args, i));
}
scc_vec_free(call->call.args);
scc_free(call);
return null;
}
scc_vec_push(call->call.args, arg);
if (!scc_parse_consume_if(parser->lex_stream,
SCC_TOK_COMMA)) {
break;
}
} while (true);
}
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_R_PAREN)) {
LOG_ERROR("expected ')' after argument list");
// 清理
scc_vec_foreach(call->call.args, i) {
scc_free(scc_vec_at(call->call.args, i));
}
scc_vec_free(call->call.args);
scc_free(call);
return null;
}
expr = call;
break;
}
case SCC_TOK_DOT: { // 成员访问
scc_lexer_stream_consume(parser->lex_stream); // 跳过 '.'
scc_ast_expr_t *member = expr_create(parser, SCC_AST_EXPR_MEMBER);
if (!member) {
scc_free(expr);
return null;
}
member->member.base = expr;
if (!scc_parse_is(parser->lex_stream, SCC_TOK_IDENT)) {
LOG_ERROR("expected identifier after '.'");
scc_free(member);
return null;
}
member->member.member_name = tok->value.cstr.data;
scc_lexer_stream_consume(parser->lex_stream); // 跳过标识符
expr = member;
break;
}
case SCC_TOK_DEREF: { // 指针成员访问 ->
scc_lexer_stream_consume(parser->lex_stream); // 跳过 '->'
scc_ast_expr_t *ptr_member =
expr_create(parser, SCC_AST_EXPR_PTR_MEMBER);
if (!ptr_member) {
scc_free(expr);
return null;
}
ptr_member->ptr_member.base = expr;
if (!scc_parse_is(parser->lex_stream, SCC_TOK_IDENT)) {
LOG_ERROR("expected identifier after '->'");
scc_free(ptr_member);
return null;
}
ptr_member->ptr_member.member_name = tok->value.cstr.data;
scc_lexer_stream_consume(parser->lex_stream); // 跳过标识符
expr = ptr_member;
break;
}
case SCC_TOK_ADD_ADD: // 后缀++
case SCC_TOK_SUB_SUB: { // 后缀--
// 跳过操作符
scc_lexer_stream_consume(parser->lex_stream);
scc_ast_expr_t *unary = expr_create(parser, SCC_AST_EXPR_UNARY);
if (!unary) {
scc_free(expr);
return null;
}
unary->unary.op = scc_ast_token_to_operator(tok->type, false);
unary->unary.operand = expr;
expr = unary;
break;
}
default:
// 不是后缀操作符,返回当前表达式
return expr;
}
// 调用语义回调
// if (parser->sema_callbacks.on_expr) {
// parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
// expr->base.type, expr);
// }
}
}
/**
* @brief 解析一元表达式
*
* (6.5.3) unary-expression:
* postfix-expression
* ++ unary-expression
* -- unary-expression
* unary-operator cast-expression
* sizeof unary-expression
* sizeof ( type-name )
*/
static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) {
const scc_lexer_tok_t *tok = scc_lexer_stream_current(parser->lex_stream);
switch (tok->type) {
case SCC_TOK_ADD_ADD: // 前缀++
case SCC_TOK_SUB_SUB: { // 前缀--
scc_lexer_stream_consume(parser->lex_stream); // 跳过操作符
scc_ast_expr_t *unary = expr_create(parser, SCC_AST_EXPR_UNARY);
if (!unary)
return null;
unary->unary.op = scc_ast_token_to_operator(tok->type, true);
unary->unary.operand = parse_unary_expression(parser);
if (!unary->unary.operand) {
scc_free(unary);
return null;
}
// if (parser->sema_callbacks.on_expr) {
// parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
// unary->node_type, unary);
// }
return unary;
}
case SCC_TOK_ADD: // +
case SCC_TOK_SUB: // -
case SCC_TOK_MUL: // *
case SCC_TOK_AND: // &
case SCC_TOK_NOT: // !
case SCC_TOK_BIT_NOT: { // ~
// 跳过操作符
scc_lexer_stream_consume(parser->lex_stream);
scc_ast_expr_t *unary = expr_create(parser, SCC_AST_EXPR_UNARY);
if (!unary)
return null;
unary->unary.op = scc_ast_token_to_operator(tok->type, true);
unary->unary.operand = parse_unary_expression(parser);
if (!unary->unary.operand) {
scc_free(unary);
return null;
}
// if (parser->sema_callbacks.on_expr) {
// parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
// unary->node_type, unary);
// }
return unary;
}
case SCC_TOK_SIZEOF: { // sizeof
// scc_lexer_stream_consume(parser->lex_stream); // 跳过 'sizeof'
// scc_ast_expr_t *size_of = expr_create(parser, SCC_AST_EXPR_SIZE_OF);
// if (!size_of)
// return null;
// size_of->size_align.is_size_of = true;
// // 检查是否是 sizeof(type) 或 sizeof expr
// if (scc_parse_consume_if(parser->lex_stream, SCC_TOK_L_PAREN)) {
// // 检查是否是类型
// // if (parser_is_type_start(parser)) {
// // size_of->size_align.type = scc_parse_type_name(parser);
// // if (!size_of->size_align.type) {
// // scc_free(size_of);
// // return null;
// // }
// // } else {
// size_of->size_align.expr = scc_parse_expression(parser);
// if (!size_of->size_align.expr) {
// scc_free(size_of);
// return null;
// }
// // }
// if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_R_PAREN)) {
// LOG_ERROR("expected ')' after sizeof");
// // if (size_of->size_align.type)
// // scc_free(size_of->size_align.type);
// // if (size_of->size_align.expr)
// // scc_free(size_of->size_align.expr);
// // scc_free(size_of);
// // return null;
// }
// } else {
// size_of->size_align.expr = parse_unary_expression(parser);
// if (!size_of->size_align.expr) {
// scc_free(size_of);
// return null;
// }
// }
// // if (parser->sema_callbacks.on_expr) {
// // parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
// // size_of->node_type, size_of);
// // }
// return size_of;
}
default:
// 不是一元操作符,解析基本表达式
scc_ast_expr_t *primary = parse_primary_expression(parser);
if (!primary)
return null;
// 应用后缀操作符
return parse_postfix_expression(parser, primary);
}
}
/**
* @brief 解析强制转换表达式
*
* (6.5.4) cast-expression:
* unary-expression
* ( type-name ) cast-expression
*/
static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) {
// 检查是否是类型转换
// if (parser_is_cast_expression(parser)) {
// // 我们已经知道是 ( type-name ) 格式
// scc_lexer_stream_consume(parser->lex_stream); // 跳过 '('
// scc_ast_type_t *type = scc_parse_type_name(parser);
// if (!type) {
// return null;
// }
// if (!parser_consume_if(parser, SCC_TOK_R_PAREN)) {
// PARSER_ERROR(parser, "expected ')' after type name");
// scc_free(type);
// return null;
// }
// scc_ast_expr_t *cast = expr_create(parser, SCC_AST_EXPR_CAST);
// if (!cast) {
// scc_free(type);
// return null;
// }
// cast->cast.type = type;
// cast->cast.expr = parse_cast_expression(parser); // 递归解析
// if (!cast->cast.expr) {
// scc_free(cast);
// return null;
// }
// if (parser->sema_callbacks.on_expr) {
// parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
// cast->node_type, cast);
// }
// return cast;
// }
// 不是类型转换,解析一元表达式
return parse_unary_expression(parser);
}
/**
* @brief Pratt Parser核心解析表达式
* @param parser 解析器
* @param min_prec 最小优先级
* @return 表达式AST节点
*/
static scc_ast_expr_t *
parse_expression_with_precedence(scc_parser_t *parser,
scc_precedence_t min_prec) {
// 解析左侧表达式(一元表达式或基本表达式)
scc_ast_expr_t *lhs = parse_cast_expression(parser);
if (!lhs) {
return null;
}
while (true) {
const scc_lexer_tok_t *tok =
scc_lexer_stream_current(parser->lex_stream);
scc_tok_type_t op = tok->type;
scc_precedence_t prec = get_binary_precedence(op);
// 检查是否达到最小优先级或不是二元运算符
if (prec < min_prec || prec == PREC_NONE) {
break;
}
// 特殊处理条件表达式 ?:
if (op == SCC_TOK_COND) {
scc_lexer_stream_consume(parser->lex_stream); // 跳过 '?'
scc_ast_expr_t *cond_expr = expr_create(parser, SCC_AST_EXPR_COND);
if (!cond_expr) {
scc_free(lhs);
return null;
}
cond_expr->cond.cond = lhs;
// 解析then表达式
cond_expr->cond.then_expr =
parse_expression_with_precedence(parser, PREC_NONE);
if (!cond_expr->cond.then_expr) {
scc_free(cond_expr);
scc_free(lhs);
return null;
}
// 期望 ':'
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_COLON)) {
LOG_ERROR("expected ':' in conditional expression");
scc_free(cond_expr);
scc_free(lhs);
return null;
}
// 解析else表达式条件表达式右结合
cond_expr->cond.else_expr =
parse_expression_with_precedence(parser, PREC_CONDITIONAL - 1);
if (!cond_expr->cond.else_expr) {
scc_free(cond_expr);
scc_free(lhs);
return null;
}
lhs = cond_expr;
continue;
}
// 对于赋值运算符右侧优先级需要减1右结合性
scc_precedence_t next_min_prec;
if (is_assignment_operator(op)) {
next_min_prec = (scc_precedence_t)(prec - 1); // 右结合
} else {
next_min_prec = (scc_precedence_t)(prec + 1); // 左结合
}
scc_lexer_stream_consume(parser->lex_stream); // 跳过操作符
// 解析右侧表达式
scc_ast_expr_t *rhs =
parse_expression_with_precedence(parser, next_min_prec);
if (!rhs) {
scc_free(lhs);
return null;
}
// 创建二元表达式节点
scc_ast_expr_t *binary = expr_create(parser, SCC_AST_EXPR_BINARY);
if (!binary) {
scc_free(lhs);
scc_free(rhs);
return null;
}
binary->binary.op = scc_ast_token_to_operator(op, false);
binary->binary.lhs = lhs;
binary->binary.rhs = rhs;
lhs = binary;
}
// if (parser->sema_callbacks.on_expr) {
// parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
// binary->node_type, binary);
// }
return lhs;
}
scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser) {
return parse_expression_with_precedence(parser, PREC_NONE);
}

View File

@@ -0,0 +1,426 @@
/*
415
ISO/IEC 9899:TC3
Committee Draft — Septermber 7, 2007
WG14/N1256
A.2.3 Statements
(6.8)
statement:
labeled-statement
compound-statement
expression-statement
selection-statement
iteration-statement
jump-statement
(6.8.1)
labeled-statement:
identifier : statement
case constant-expression : statement
default : statement
(6.8.2)
compound-statement:
{ block-item-list(opt) }
(6.8.2)
block-item-list:
block-item
block-item-list block-item
(6.8.2)
block-item:
declaration
statement
(6.8.3)
expression-statement:
expression(opt) ;
(6.8.4)
selection-statement:
if ( expression ) statement
if ( expression ) statement else statement
switch ( expression ) statement
(6.8.5)
iteration-statement:
while ( expression ) statement
do statement while ( expression );
for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
for ( declaration expression(opt) ; expression(opt) ) statement
(6.8.6)
jump-statement:
goto identifier ;
continue ;
break ;
return expression(opt) ;
*/
#include <parser.h>
static inline scc_ast_stmt_t *ast_stmt_alloc() {
scc_ast_stmt_t *stmt = (scc_ast_stmt_t *)scc_malloc(sizeof(scc_ast_stmt_t));
Assert(stmt != null);
stmt->base.type = SCC_AST_TRANSLATION_UNIT;
stmt->base.loc = scc_pos_create();
return stmt;
}
static inline scc_ast_expr_t *ast_parse_paren_expression(scc_parser_t *parser) {
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_L_PAREN)) {
LOG_ERROR("Expected '(' before like `( expression )` .");
}
scc_ast_expr_t *ret = scc_parse_expression(parser);
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_R_PAREN)) {
LOG_ERROR("Expected ')' after like `( expression )` .");
}
return ret;
}
static scc_ast_stmt_t *parse_label_statement(scc_parser_t *parser) {
const scc_lexer_tok_t *tok = scc_lexer_stream_current(parser->lex_stream);
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_IDENT)) {
return null;
}
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_COLON)) {
LOG_ERROR("Expected constant expression after case.");
return null;
}
scc_ast_stmt_t *statement = scc_parse_statement(parser);
if (statement == null) {
Panic("expect stmt");
}
scc_ast_stmt_t *stmt = ast_stmt_alloc();
Assert(stmt != null);
stmt->base.type = SCC_AST_STMT_LABEL;
// TODO maybe use cstring
stmt->label_stmt.label = tok->value.cstr.data;
stmt->label_stmt.stmt = statement;
return stmt;
}
static scc_ast_stmt_t *parse_case_statement(scc_parser_t *parser) {
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_CASE)) {
return null;
}
scc_ast_expr_t *expr = null;
// TODO = scc_parser_constant_expression();
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_COLON)) {
LOG_ERROR("Expected constant expression after case.");
return null;
}
scc_ast_stmt_t *statement = scc_parse_statement(parser);
if (statement == null) {
Panic("expect stmt");
}
scc_ast_stmt_t *stmt = ast_stmt_alloc();
Assert(stmt != null);
stmt->case_stmt.expr = expr;
stmt->base.type = SCC_AST_STMT_CASE;
stmt->case_stmt.stmt = statement;
return stmt;
}
static scc_ast_stmt_t *parse_default_statement(scc_parser_t *parser) {
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_DEFAULT)) {
return null;
}
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_COLON)) {
LOG_ERROR("Expected constant expression after case.");
return null;
}
scc_ast_stmt_t *statement = scc_parse_statement(parser);
if (statement == null) {
Panic("expect stmt");
}
scc_ast_stmt_t *stmt = ast_stmt_alloc();
Assert(stmt != null);
stmt->base.type = SCC_AST_STMT_DEFAULT;
stmt->default_stmt.stmt = statement;
return stmt;
}
static scc_ast_stmt_t *parse_compound_statement(scc_parser_t *parser) {
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_L_BRACE)) {
return null;
}
scc_ast_stmt_t *stmt = ast_stmt_alloc();
stmt->base.type = SCC_AST_STMT_COMPOUND;
scc_vec_init(stmt->compound.block_items);
while (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_R_BRACE)) {
/// TODO
// scc_parse_is_decl();
scc_ast_node_type_t *ret = null;
ret = (scc_ast_node_type_t *)scc_parse_declaration(parser);
if (ret == null) {
ret = (scc_ast_node_type_t *)scc_parse_statement(parser);
}
if (ret == null) {
LOG_ERROR("Invalid statement");
// TODO
scc_free(stmt);
return null;
}
scc_vec_push(stmt->compound.block_items, ret);
}
return stmt;
}
static scc_ast_stmt_t *parse_if_statement(scc_parser_t *parser) {
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_IF)) {
return null;
}
scc_ast_expr_t *expression = ast_parse_paren_expression(parser);
scc_ast_stmt_t *statement = scc_parse_statement(parser);
scc_ast_stmt_t *stmt = ast_stmt_alloc();
stmt->base.type = SCC_AST_STMT_IF;
stmt->if_stmt.cond = expression;
stmt->if_stmt.then_stmt = statement;
if (scc_parse_consume_if(parser->lex_stream, SCC_TOK_ELSE)) {
stmt->if_stmt.opt_else_stmt = scc_parse_statement(parser);
} else {
stmt->if_stmt.opt_else_stmt = null;
}
return stmt;
}
static scc_ast_stmt_t *parse_switch_statement(scc_parser_t *parser) {
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_SWITCH)) {
return null;
}
scc_ast_expr_t *expression = ast_parse_paren_expression(parser);
scc_ast_stmt_t *statement = scc_parse_statement(parser);
scc_ast_stmt_t *stmt = ast_stmt_alloc();
stmt->base.type = SCC_AST_STMT_SWITCH;
stmt->switch_stmt.cond = expression;
stmt->switch_stmt.body = statement;
return stmt;
}
static scc_ast_stmt_t *parse_while_statement(scc_parser_t *parser) {
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_WHILE)) {
return null;
}
scc_ast_expr_t *expression = ast_parse_paren_expression(parser);
scc_ast_stmt_t *statement = scc_parse_statement(parser);
scc_ast_stmt_t *stmt = ast_stmt_alloc();
stmt->base.type = SCC_AST_STMT_WHILE;
stmt->while_stmt.cond = expression;
stmt->while_stmt.body = statement;
return stmt;
}
static scc_ast_stmt_t *parse_do_while_statement(scc_parser_t *parser) {
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_DO)) {
return null;
}
scc_ast_stmt_t *statement = scc_parse_statement(parser);
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_WHILE)) {
LOG_ERROR("Expected 'while' after do.");
// TODO 使用更好的错误处理,未来应当采用更好的内存管理器
scc_free(statement);
return null;
}
scc_ast_expr_t *expression = ast_parse_paren_expression(parser);
scc_ast_stmt_t *stmt = ast_stmt_alloc();
stmt->base.type = SCC_AST_STMT_DO_WHILE;
stmt->do_while_stmt.cond = expression;
stmt->do_while_stmt.body = statement;
return stmt;
}
static scc_ast_stmt_t *parse_for_statement(scc_parser_t *parser) {
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_FOR)) {
return null;
}
/*
for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
for ( declaration expression(opt) ; expression(opt) ) statement
*/
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_L_PAREN)) {
LOG_ERROR("Expected '(' before like `( expression )` .");
}
scc_ast_stmt_t *stmt = ast_stmt_alloc();
stmt->base.type = SCC_AST_STMT_FOR;
// TODO use decl or expr
stmt->for_stmt.init = (scc_ast_type_t *)scc_parse_expression(parser);
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_SEMICOLON)) {
LOG_ERROR("Expected semicolon in for statement.");
}
stmt->for_stmt.cond = scc_parse_expression(parser);
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_SEMICOLON)) {
LOG_ERROR("Expected semicolon in for statement.");
}
stmt->for_stmt.iter = scc_parse_expression(parser);
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_R_PAREN)) {
LOG_ERROR("Expected ')' after like `( expression )` .");
}
stmt->for_stmt.body = scc_parse_statement(parser);
return stmt;
}
static scc_ast_stmt_t *parse_jump_statement(scc_parser_t *parser) {
scc_ast_stmt_t *stmt = ast_stmt_alloc();
if (scc_parse_consume_if(parser->lex_stream, SCC_TOK_GOTO)) {
stmt->base.type = SCC_AST_STMT_GOTO;
if (scc_parse_is(parser->lex_stream, SCC_TOK_IDENT)) {
const scc_lexer_tok_t *tok =
scc_lexer_stream_current(parser->lex_stream);
stmt->goto_stmt.label = tok->value.cstr.data;
scc_lexer_stream_consume(parser->lex_stream);
} else {
LOG_ERROR("Expected label after goto.");
}
} else if (scc_parse_consume_if(parser->lex_stream, SCC_TOK_CONTINUE)) {
stmt->base.type = SCC_AST_STMT_CONTINUE;
} else if (scc_parse_consume_if(parser->lex_stream, SCC_TOK_BREAK)) {
stmt->base.type = SCC_AST_STMT_BREAK;
} else if (scc_parse_consume_if(parser->lex_stream, SCC_TOK_RETURN)) {
stmt->base.type = SCC_AST_STMT_RETURN;
stmt->return_stmt.expr = scc_parse_expression(parser);
} else {
UNREACHABLE();
}
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_SEMICOLON)) {
LOG_ERROR("Expected semicolon after jump statement.");
}
return stmt;
}
static scc_ast_stmt_t *parse_expression_statement(scc_parser_t *parser) {
scc_ast_stmt_t *stmt = ast_stmt_alloc();
stmt->base.type = SCC_AST_STMT_EXPR;
if (scc_parse_consume_if(parser->lex_stream, SCC_TOK_SEMICOLON)) {
stmt->expr.expr = null;
return stmt;
}
stmt->expr.expr = scc_parse_expression(parser);
if (stmt->expr.expr == null) {
// TODO
scc_free(stmt);
return null;
}
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_SEMICOLON)) {
LOG_ERROR("Expected semicolon after expression.");
}
return stmt;
}
scc_ast_stmt_t *scc_parse_statement(scc_parser_t *parser) {
const scc_lexer_tok_t *tok = scc_lexer_stream_current(parser->lex_stream);
switch (tok->type) {
/*
(6.8.1)
labeled-statement:
identifier : statement
case constant-expression : statement
default : statement
*/
case SCC_TOK_IDENT:
// 注意需要检测下一个 token 是否为冒号,否则将需要判定成表达式语句
if (!scc_parse_peek_is(parser->lex_stream, 1, SCC_TOK_COLON)) {
break;
}
return parse_label_statement(parser);
case SCC_TOK_CASE:
return parse_case_statement(parser);
case SCC_TOK_DEFAULT:
return parse_default_statement(parser);
/*
(6.8.2)
compound-statement:
{ block-item-list(opt) }
(6.8.2)
block-item-list:
block-item
block-item-list block-item
(6.8.2)
block-item:
declaration
statement
*/
case SCC_TOK_L_BRACE:
return parse_compound_statement(parser);
/*
(6.8.4)
selection-statement:
if ( expression ) statement
if ( expression ) statement else statement
switch ( expression ) statement
*/
case SCC_TOK_IF:
return parse_if_statement(parser);
case SCC_TOK_SWITCH:
return parse_switch_statement(parser);
/*
(6.8.5)
iteration-statement:
while ( expression ) statement
do statement while ( expression );
for ( expression(opt) ; expression(opt) ; expression(opt) )
statement
for ( declaration expression(opt) ; expression(opt) )
statement
*/
case SCC_TOK_WHILE:
return parse_while_statement(parser);
case SCC_TOK_DO:
return parse_do_while_statement(parser);
case SCC_TOK_FOR:
return parse_for_statement(parser);
/*
(6.8.6)
jump-statement:
goto identifier ;
continue ;
break ;
return expression(opt) ;
*/
case SCC_TOK_GOTO:
case SCC_TOK_CONTINUE:
case SCC_TOK_BREAK:
case SCC_TOK_RETURN:
return parse_jump_statement(parser);
default:
break;
}
/*
(6.8.3)
expression-statement:
expression(opt) ;
*/
return parse_expression_statement(parser);
}

1055
libs/parser/src/parse_type.c Normal file

File diff suppressed because it is too large Load Diff

85
libs/parser/src/parser.c Normal file
View File

@@ -0,0 +1,85 @@
/**
* @file parser.c
* @brief 新的解析器实现
*/
#include "parser.h"
#include <log.h>
static void dummy_sema_callback(void *context, scc_ast_node_type_t node_type,
void *node) {
(void)context;
(void)node_type;
(void)node;
return;
}
#define ASSIGN_PTR_OR_DEFAULT(assigned_val, value, default) \
assigned_val = value ? value : default
void scc_parser_init(scc_parser_t *parser, scc_lexer_stream_t *lexer,
scc_sema_callbacks_t *callbacks) {
Assert(parser != null && lexer != null);
parser->lex_stream = lexer;
parser->has_error = false;
parser->translation_unit = null;
if (callbacks) {
ASSIGN_PTR_OR_DEFAULT(parser->sema_callbacks.on_decl,
callbacks->on_decl, dummy_sema_callback);
ASSIGN_PTR_OR_DEFAULT(parser->sema_callbacks.on_stmt,
callbacks->on_stmt, dummy_sema_callback);
ASSIGN_PTR_OR_DEFAULT(parser->sema_callbacks.on_expr,
callbacks->on_expr, dummy_sema_callback);
ASSIGN_PTR_OR_DEFAULT(parser->sema_callbacks.on_type,
callbacks->on_type, dummy_sema_callback);
parser->sema_callbacks.context = callbacks->context;
} else {
parser->sema_callbacks.on_decl = dummy_sema_callback;
parser->sema_callbacks.on_stmt = dummy_sema_callback;
parser->sema_callbacks.on_expr = dummy_sema_callback;
parser->sema_callbacks.on_type = dummy_sema_callback;
parser->sema_callbacks.context = dummy_sema_callback;
}
// // ONLY FOR INIT TYPE
// parser->current_token.type = SCC_TOK_UNKNOWN;
}
void scc_parser_drop(scc_parser_t *parser) {
// TODO: 释放 AST 内存
(void)parser;
}
scc_ast_translation_unit_t *scc_parse_translation_unit(scc_parser_t *parser) {
scc_ast_translation_unit_t *unit =
scc_malloc(sizeof(scc_ast_translation_unit_t));
if (!unit)
return null;
unit->base.type = SCC_AST_TRANSLATION_UNIT;
scc_vec_init(unit->declarations);
/**
* Program := (Declaration | Definition)*
* same as
* Program := Declaration* Definition*
*/
do {
scc_ast_decl_t *decl = scc_parse_declaration(parser);
if (decl != null) {
scc_vec_push(unit->declarations, decl);
} else {
break;
// MAYBE return or next
}
} while (!scc_lexer_tok_match(scc_lexer_stream_current(parser->lex_stream),
SCC_TOK_EOF) &&
!parser->has_error);
if (parser->has_error) {
// TODO: 清理
scc_free(unit);
return null;
}
Assert(unit->base.type == SCC_AST_TRANSLATION_UNIT);
return unit;
}