feat add func call and rewrite codes
This commit is contained in:
@ -14,9 +14,9 @@ void init_ast_node(struct ASTNode* node) {
|
||||
}
|
||||
}
|
||||
|
||||
struct ASTNode* find_ast_node(struct ASTNode* node, enum ASTType type) {
|
||||
// struct ASTNode* find_ast_node(struct ASTNode* node, ast_type_t type) {
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
#include <stdio.h>
|
||||
static void pnt_depth(int depth) {
|
||||
@ -25,149 +25,149 @@ static void pnt_depth(int depth) {
|
||||
}
|
||||
}
|
||||
|
||||
void pnt_ast(struct ASTNode* node, int depth) {
|
||||
if (!node) return;
|
||||
pnt_depth(depth);
|
||||
switch (node->type) {
|
||||
case NT_ROOT:
|
||||
for (int i = 0; i < node->root.child_size; i++) {
|
||||
pnt_ast(node->root.children[i], depth);
|
||||
}
|
||||
return;
|
||||
// void pnt_ast(struct ASTNode* node, int depth) {
|
||||
// if (!node) return;
|
||||
// pnt_depth(depth);
|
||||
// switch (node->type) {
|
||||
// case NT_ROOT:
|
||||
// for (int i = 0; i < node->root.child_size; i++) {
|
||||
// pnt_ast(node->root.children[i], depth);
|
||||
// }
|
||||
// return;
|
||||
|
||||
case NT_ADD : printf("+ \n"); break; // (expr) + (expr)
|
||||
case NT_SUB : printf("- \n"); break; // (expr) - (expr)
|
||||
case NT_MUL : printf("* \n"); break; // (expr) * (expr)
|
||||
case NT_DIV : printf("/ \n"); break; // (expr) / (expr)
|
||||
case NT_MOD : printf("%%\n"); break; // (expr) % (expr)
|
||||
case NT_AND : printf("& \n"); break; // (expr) & (expr)
|
||||
case NT_OR : printf("| \n"); break; // (expr) | (expr)
|
||||
case NT_XOR : printf("^ \n"); break; // (expr) ^ (expr)
|
||||
case NT_L_SH : printf("<<\n"); break; // (expr) << (expr)
|
||||
case NT_R_SH : printf(">>\n"); break; // (expr) >> (expr)
|
||||
case NT_EQ : printf("==\n"); break; // (expr) == (expr)
|
||||
case NT_NEQ : printf("!=\n"); break; // (expr) != (expr)
|
||||
case NT_LE : printf("<=\n"); break; // (expr) <= (expr)
|
||||
case NT_GE : printf(">=\n"); break; // (expr) >= (expr)
|
||||
case NT_LT : printf("< \n"); break; // (expr) < (expr)
|
||||
case NT_GT : printf("> \n"); break; // (expr) > (expr)
|
||||
case NT_AND_AND : printf("&&\n"); break; // (expr) && (expr)
|
||||
case NT_OR_OR : printf("||\n"); break; // (expr) || (expr)
|
||||
case NT_NOT : printf("! \n"); break; // ! (expr)
|
||||
case NT_BIT_NOT : printf("~ \n"); break; // ~ (expr)
|
||||
case NT_COMMA : printf(", \n"); break; // expr, expr 逗号运算符
|
||||
case NT_ASSIGN : printf("= \n"); break; // (expr) = (expr)
|
||||
// case NT_COND : // (expr) ? (expr) : (expr)
|
||||
// case NT_ADD : printf("+ \n"); break; // (expr) + (expr)
|
||||
// case NT_SUB : printf("- \n"); break; // (expr) - (expr)
|
||||
// case NT_MUL : printf("* \n"); break; // (expr) * (expr)
|
||||
// case NT_DIV : printf("/ \n"); break; // (expr) / (expr)
|
||||
// case NT_MOD : printf("%%\n"); break; // (expr) % (expr)
|
||||
// case NT_AND : printf("& \n"); break; // (expr) & (expr)
|
||||
// case NT_OR : printf("| \n"); break; // (expr) | (expr)
|
||||
// case NT_XOR : printf("^ \n"); break; // (expr) ^ (expr)
|
||||
// case NT_L_SH : printf("<<\n"); break; // (expr) << (expr)
|
||||
// case NT_R_SH : printf(">>\n"); break; // (expr) >> (expr)
|
||||
// case NT_EQ : printf("==\n"); break; // (expr) == (expr)
|
||||
// case NT_NEQ : printf("!=\n"); break; // (expr) != (expr)
|
||||
// case NT_LE : printf("<=\n"); break; // (expr) <= (expr)
|
||||
// case NT_GE : printf(">=\n"); break; // (expr) >= (expr)
|
||||
// case NT_LT : printf("< \n"); break; // (expr) < (expr)
|
||||
// case NT_GT : printf("> \n"); break; // (expr) > (expr)
|
||||
// case NT_AND_AND : printf("&&\n"); break; // (expr) && (expr)
|
||||
// case NT_OR_OR : printf("||\n"); break; // (expr) || (expr)
|
||||
// case NT_NOT : printf("! \n"); break; // ! (expr)
|
||||
// case NT_BIT_NOT : printf("~ \n"); break; // ~ (expr)
|
||||
// case NT_COMMA : printf(", \n"); break; // expr, expr 逗号运算符
|
||||
// case NT_ASSIGN : printf("= \n"); break; // (expr) = (expr)
|
||||
// // case NT_COND : // (expr) ? (expr) : (expr)
|
||||
|
||||
case NT_STMT_EMPTY : // ;
|
||||
printf(";\n");
|
||||
break;
|
||||
case NT_STMT_IF : // if (cond) { ... } [else {...}]
|
||||
printf("if");
|
||||
pnt_ast(node->if_stmt.cond, depth+1);
|
||||
pnt_ast(node->if_stmt.if_stmt, depth+1);
|
||||
if (node->if_stmt.else_stmt) {
|
||||
pnt_depth(depth);
|
||||
printf("else");
|
||||
pnt_ast(node->if_stmt.else_stmt, depth+1);
|
||||
}
|
||||
break;
|
||||
case NT_STMT_WHILE : // while (cond) { ... }
|
||||
printf("while\n");
|
||||
pnt_ast(node->while_stmt.cond, depth+1);
|
||||
pnt_ast(node->while_stmt.body, depth+1);
|
||||
break;
|
||||
case NT_STMT_DOWHILE : // do {...} while (cond)
|
||||
printf("do-while\n");
|
||||
pnt_ast(node->do_while_stmt.body, depth+1);
|
||||
pnt_ast(node->do_while_stmt.cond, depth+1);
|
||||
break;
|
||||
case NT_STMT_FOR : // for (init; cond; iter) {...}
|
||||
printf("for\n");
|
||||
if (node->for_stmt.init)
|
||||
pnt_ast(node->for_stmt.init, depth+1);
|
||||
if (node->for_stmt.cond)
|
||||
pnt_ast(node->for_stmt.cond, depth+1);
|
||||
if (node->for_stmt.iter)
|
||||
pnt_ast(node->for_stmt.iter, depth+1);
|
||||
pnt_ast(node->for_stmt.body, depth+1);
|
||||
break;
|
||||
case NT_STMT_SWITCH : // switch (expr) { case ... }
|
||||
case NT_STMT_BREAK : // break;
|
||||
case NT_STMT_CONTINUE : // continue;
|
||||
case NT_STMT_GOTO : // goto label;
|
||||
case NT_STMT_CASE : // case const_expr:
|
||||
case NT_STMT_DEFAULT : // default:
|
||||
case NT_STMT_LABEL : // label:
|
||||
break;
|
||||
case NT_STMT_BLOCK : // { ... }
|
||||
printf("{\n");
|
||||
for (int i = 0; i < node->block.child_size; i++) {
|
||||
pnt_ast(node->block.children[i], depth+1);
|
||||
}
|
||||
pnt_depth(depth);
|
||||
printf("}\n");
|
||||
break;
|
||||
case NT_STMT_RETURN : // return expr;
|
||||
printf("return");
|
||||
if (node->return_stmt.expr_stmt) {
|
||||
printf(" ");
|
||||
pnt_ast(node->return_stmt.expr_stmt, depth+1);
|
||||
} else {
|
||||
printf("\n");
|
||||
}
|
||||
break;
|
||||
case NT_STMT_EXPR : // expr;
|
||||
printf("stmt\n");
|
||||
pnt_ast(node->expr_stmt.expr_stmt, depth);
|
||||
pnt_depth(depth);
|
||||
printf(";\n");
|
||||
break;
|
||||
case NT_DECL_VAR : // type name; or type name = expr;
|
||||
printf("decl_val\n");
|
||||
break;
|
||||
case NT_DECL_FUNC: // type func_name(param_list);
|
||||
printf("decl func %s\n", node->func.name->syms.tok.constant.str);
|
||||
break;
|
||||
case NT_FUNC : // type func_name(param_list) {...}
|
||||
printf("def func %s\n", node->func.name->syms.tok.constant.str);
|
||||
// pnt_ast(node->child.func.params, depth);
|
||||
pnt_ast(node->func.body, depth);
|
||||
// pnt_ast(node->child.func.ret, depth);
|
||||
break;
|
||||
case NT_PARAM : // 函数形参
|
||||
printf("param\n");
|
||||
case NT_ARG_LIST : // 实参列表(需要与NT_CALL配合)
|
||||
printf("arg_list\n");
|
||||
case NT_TERM_CALL : // func (expr)
|
||||
printf("call\n");
|
||||
break;
|
||||
case NT_TERM_IDENT:
|
||||
printf("%s\n", node->syms.tok.constant.str);
|
||||
break;
|
||||
case NT_TERM_VAL : // Terminal Symbols like constant, identifier, keyword
|
||||
struct Token * tok = &node->syms.tok;
|
||||
switch (tok->type) {
|
||||
case TOKEN_CHAR_LITERAL:
|
||||
printf("%c\n", tok->constant.ch);
|
||||
break;
|
||||
case TOKEN_INT_LITERAL:
|
||||
printf("%d\n", tok->constant.i);
|
||||
break;
|
||||
case TOKEN_STRING_LITERAL:
|
||||
printf("%s\n", tok->constant.str);
|
||||
break;
|
||||
default:
|
||||
printf("unknown term val\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// case NT_STMT_EMPTY : // ;
|
||||
// printf(";\n");
|
||||
// break;
|
||||
// case NT_STMT_IF : // if (cond) { ... } [else {...}]
|
||||
// printf("if");
|
||||
// pnt_ast(node->if_stmt.cond, depth+1);
|
||||
// pnt_ast(node->if_stmt.if_stmt, depth+1);
|
||||
// if (node->if_stmt.else_stmt) {
|
||||
// pnt_depth(depth);
|
||||
// printf("else");
|
||||
// pnt_ast(node->if_stmt.else_stmt, depth+1);
|
||||
// }
|
||||
// break;
|
||||
// case NT_STMT_WHILE : // while (cond) { ... }
|
||||
// printf("while\n");
|
||||
// pnt_ast(node->while_stmt.cond, depth+1);
|
||||
// pnt_ast(node->while_stmt.body, depth+1);
|
||||
// break;
|
||||
// case NT_STMT_DOWHILE : // do {...} while (cond)
|
||||
// printf("do-while\n");
|
||||
// pnt_ast(node->do_while_stmt.body, depth+1);
|
||||
// pnt_ast(node->do_while_stmt.cond, depth+1);
|
||||
// break;
|
||||
// case NT_STMT_FOR : // for (init; cond; iter) {...}
|
||||
// printf("for\n");
|
||||
// if (node->for_stmt.init)
|
||||
// pnt_ast(node->for_stmt.init, depth+1);
|
||||
// if (node->for_stmt.cond)
|
||||
// pnt_ast(node->for_stmt.cond, depth+1);
|
||||
// if (node->for_stmt.iter)
|
||||
// pnt_ast(node->for_stmt.iter, depth+1);
|
||||
// pnt_ast(node->for_stmt.body, depth+1);
|
||||
// break;
|
||||
// case NT_STMT_SWITCH : // switch (expr) { case ... }
|
||||
// case NT_STMT_BREAK : // break;
|
||||
// case NT_STMT_CONTINUE : // continue;
|
||||
// case NT_STMT_GOTO : // goto label;
|
||||
// case NT_STMT_CASE : // case const_expr:
|
||||
// case NT_STMT_DEFAULT : // default:
|
||||
// case NT_STMT_LABEL : // label:
|
||||
// break;
|
||||
// case NT_STMT_BLOCK : // { ... }
|
||||
// printf("{\n");
|
||||
// for (int i = 0; i < node->block.child_size; i++) {
|
||||
// pnt_ast(node->block.children[i], depth+1);
|
||||
// }
|
||||
// pnt_depth(depth);
|
||||
// printf("}\n");
|
||||
// break;
|
||||
// case NT_STMT_RETURN : // return expr;
|
||||
// printf("return");
|
||||
// if (node->return_stmt.expr_stmt) {
|
||||
// printf(" ");
|
||||
// pnt_ast(node->return_stmt.expr_stmt, depth+1);
|
||||
// } else {
|
||||
// printf("\n");
|
||||
// }
|
||||
// break;
|
||||
// case NT_STMT_EXPR : // expr;
|
||||
// printf("stmt\n");
|
||||
// pnt_ast(node->expr_stmt.expr_stmt, depth);
|
||||
// pnt_depth(depth);
|
||||
// printf(";\n");
|
||||
// break;
|
||||
// case NT_DECL_VAR : // type name; or type name = expr;
|
||||
// printf("decl_val\n");
|
||||
// break;
|
||||
// case NT_DECL_FUNC: // type func_name(param_list);
|
||||
// printf("decl func %s\n", node->func.name->syms.tok.val.str);
|
||||
// break;
|
||||
// case NT_FUNC : // type func_name(param_list) {...}
|
||||
// printf("def func %s\n", node->func.name->syms.tok.val.str);
|
||||
// // pnt_ast(node->child.func.params, depth);
|
||||
// pnt_ast(node->func.body, depth);
|
||||
// // pnt_ast(node->child.func.ret, depth);
|
||||
// break;
|
||||
// case NT_PARAM : // 函数形参
|
||||
// printf("param\n");
|
||||
// case NT_ARG_LIST : // 实参列表(需要与NT_CALL配合)
|
||||
// printf("arg_list\n");
|
||||
// case NT_TERM_CALL : // func (expr)
|
||||
// printf("call\n");
|
||||
// break;
|
||||
// case NT_TERM_IDENT:
|
||||
// printf("%s\n", node->syms.tok.val.str);
|
||||
// break;
|
||||
// case NT_TERM_VAL : // Terminal Symbols like constant, identifier, keyword
|
||||
// tok_t * tok = &node->syms.tok;
|
||||
// switch (tok->type) {
|
||||
// case TOKEN_CHAR_LITERAL:
|
||||
// printf("%c\n", tok->val.ch);
|
||||
// break;
|
||||
// case TOKEN_INT_LITERAL:
|
||||
// printf("%d\n", tok->val.i);
|
||||
// break;
|
||||
// case TOKEN_STRING_LITERAL:
|
||||
// printf("%s\n", tok->val.str);
|
||||
// break;
|
||||
// default:
|
||||
// printf("unknown term val\n");
|
||||
// break;
|
||||
// }
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
|
||||
// 通用子节点递归处理
|
||||
if (node->type <= NT_ASSIGN) { // 表达式类统一处理子节点
|
||||
if (node->expr.left) pnt_ast(node->expr.left, depth+1);
|
||||
if (node->expr.right) pnt_ast(node->expr.right, depth + 1);
|
||||
}
|
||||
}
|
||||
// // 通用子节点递归处理
|
||||
// if (node->type <= NT_ASSIGN) { // 表达式类统一处理子节点
|
||||
// if (node->expr.left) pnt_ast(node->expr.left, depth+1);
|
||||
// if (node->expr.right) pnt_ast(node->expr.right, depth + 1);
|
||||
// }
|
||||
// }
|
||||
|
@ -3,9 +3,10 @@
|
||||
|
||||
#include "../../frontend.h"
|
||||
#include "../../lexer/lexer.h"
|
||||
#include "../../../../libcore/vector.h"
|
||||
#include "../type.h"
|
||||
|
||||
enum ASTType {
|
||||
typedef enum {
|
||||
NT_INIT,
|
||||
NT_ROOT, // global scope in root node
|
||||
NT_ADD, // (expr) + (expr)
|
||||
@ -75,31 +76,28 @@ enum ASTType {
|
||||
NT_TERM_VAL,
|
||||
NT_TERM_IDENT,
|
||||
NT_TERM_TYPE,
|
||||
};
|
||||
} ast_type_t;
|
||||
|
||||
struct ASTNode {
|
||||
enum ASTType type;
|
||||
typedef struct ASTNode {
|
||||
ast_type_t type;
|
||||
|
||||
union {
|
||||
void *children[6];
|
||||
struct {
|
||||
struct ASTNode** children;
|
||||
int child_size;
|
||||
vector_header(children, struct ASTNode*);
|
||||
} root;
|
||||
struct {
|
||||
struct ASTNode** children; // array of children
|
||||
int child_size;
|
||||
vector_header(children, struct ASTNode*);
|
||||
} block;
|
||||
struct {
|
||||
struct ASTNode* decl_node;
|
||||
struct Token tok;
|
||||
tok_t tok;
|
||||
} syms;
|
||||
struct {
|
||||
struct ASTNode *arr;
|
||||
int size;
|
||||
vector_header(params, struct ASTNode*);
|
||||
} params;
|
||||
struct {
|
||||
const char* name;
|
||||
struct ASTNode* name;
|
||||
struct ASTNode* params;
|
||||
struct ASTNode* func_decl;
|
||||
} call;
|
||||
@ -113,13 +111,12 @@ struct ASTNode {
|
||||
struct ASTNode *ret;
|
||||
struct ASTNode *name;
|
||||
struct ASTNode *params; // array of params
|
||||
void* data;
|
||||
} func_decl;
|
||||
struct ASTNode *def;
|
||||
} decl_func;
|
||||
struct {
|
||||
struct ASTNode *ret;
|
||||
struct ASTNode *name;
|
||||
struct ASTNode *params; // array of params
|
||||
struct ASTNode *decl;
|
||||
struct ASTNode *body; // optional
|
||||
void* data;
|
||||
} func;
|
||||
struct {
|
||||
struct ASTNode *left;
|
||||
@ -165,27 +162,26 @@ struct ASTNode {
|
||||
struct ASTNode *expr_stmt;
|
||||
} expr_stmt;
|
||||
};
|
||||
};
|
||||
} ast_node_t;
|
||||
|
||||
struct ASTNode* new_ast_node(void);
|
||||
void init_ast_node(struct ASTNode* node);
|
||||
void pnt_ast(struct ASTNode* node, int depth);
|
||||
|
||||
struct Parser;
|
||||
typedef struct ASTNode* (*parse_func_t) (struct Parser*);
|
||||
typedef struct parser parser_t;
|
||||
typedef struct ASTNode* (*parse_func_t) (parser_t*);
|
||||
|
||||
void parse_prog(struct Parser* parser);
|
||||
struct ASTNode* parse_block(struct Parser* parser);
|
||||
struct ASTNode* parse_stmt(struct Parser* parser);
|
||||
struct ASTNode* parse_expr(struct Parser* parser);
|
||||
struct ASTNode* parse_func(struct Parser* parser);
|
||||
struct ASTNode* parse_decl(struct Parser* parser);
|
||||
void parse_prog(parser_t* parser);
|
||||
ast_node_t* parse_decl(parser_t* parser);
|
||||
ast_node_t* parse_block(parser_t* parser);
|
||||
ast_node_t* parse_stmt(parser_t* parser);
|
||||
ast_node_t* parse_expr(parser_t* parser);
|
||||
|
||||
struct ASTNode* parse_ident(struct Parser* parser);
|
||||
struct ASTNode* parse_type(struct Parser* parser);
|
||||
ast_node_t* parse_type(parser_t* parser);
|
||||
|
||||
int peek_decl(struct Parser* parser);
|
||||
ast_node_t* new_ast_ident_node(tok_t* tok);
|
||||
ast_node_t* expect_pop_ident(tok_buf_t* tokbuf);
|
||||
|
||||
struct ASTNode* parser_ident_without_pop(struct Parser* parser);
|
||||
int peek_decl(tok_buf_t* tokbuf);
|
||||
|
||||
#endif
|
||||
|
@ -1,48 +1,49 @@
|
||||
|
||||
#include "../parser.h"
|
||||
#include "ast.h"
|
||||
#include "../parser.h"
|
||||
#include "../symtab/symtab.h"
|
||||
|
||||
|
||||
#ifndef BLOCK_MAX_NODE
|
||||
#define BLOCK_MAX_NODE (1024)
|
||||
#endif
|
||||
|
||||
struct ASTNode* parse_block(struct Parser* parser) {
|
||||
symtab_enter_scope(parser->symtab);
|
||||
|
||||
// parse_decl(parser); // decl_var
|
||||
enum TokenType ttype;
|
||||
struct ASTNode* node = new_ast_node();
|
||||
ast_node_t* new_ast_node_block() {
|
||||
ast_node_t* node = new_ast_node();
|
||||
node->type = NT_BLOCK;
|
||||
flushpeektok(parser);
|
||||
ttype = peektoktype(parser);
|
||||
if (ttype != TOKEN_L_BRACE) {
|
||||
error("block need '{' start");
|
||||
}
|
||||
poptok(parser);
|
||||
vector_init(node->block.children);
|
||||
return node;
|
||||
}
|
||||
|
||||
node->block.children = malloc(sizeof(struct ASTNode*) * BLOCK_MAX_NODE);
|
||||
struct ASTNode* child = NULL;
|
||||
ast_node_t* parse_block(parser_t* parser) {
|
||||
symtab_enter_scope(parser->symtab);
|
||||
tok_buf_t *tokbuf = &parser->tokbuf;
|
||||
flush_peek_tok(tokbuf);
|
||||
tok_type_t ttype;
|
||||
ast_node_t* node = new_ast_node_block();
|
||||
|
||||
expect_pop_tok(tokbuf, TOKEN_L_BRACE);
|
||||
ast_node_t* child = NULL;
|
||||
while (1) {
|
||||
if (peek_decl(parser) == 1) {
|
||||
if (peek_decl(tokbuf)) {
|
||||
child = parse_decl(parser);
|
||||
goto ADD_CHILD;
|
||||
vector_push(node->block.children, child);
|
||||
continue;
|
||||
}
|
||||
|
||||
flushpeektok(parser);
|
||||
ttype = peektoktype(parser);
|
||||
flush_peek_tok(tokbuf);
|
||||
ttype = peek_tok_type(tokbuf);
|
||||
switch (ttype) {
|
||||
case TOKEN_R_BRACE:
|
||||
poptok(parser);
|
||||
goto END;
|
||||
default:
|
||||
child = parse_stmt(parser);
|
||||
goto ADD_CHILD;
|
||||
break;
|
||||
case TOKEN_R_BRACE: {
|
||||
pop_tok(tokbuf);
|
||||
goto END;
|
||||
}
|
||||
default: {
|
||||
child = parse_stmt(parser);
|
||||
vector_push(node->block.children, child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
ADD_CHILD:
|
||||
node->block.children[node->block.child_size++] = child;
|
||||
}
|
||||
END:
|
||||
symtab_leave_scope(parser->symtab);
|
||||
|
@ -6,9 +6,9 @@
|
||||
* 0 false
|
||||
* 1 true
|
||||
*/
|
||||
int peek_decl(struct Parser* parser) {
|
||||
flushpeektok(parser);
|
||||
switch (peektoktype(parser)) {
|
||||
int peek_decl(tok_buf_t* tokbuf) {
|
||||
flush_peek_tok(tokbuf);
|
||||
switch (peek_tok_type(tokbuf)) {
|
||||
case TOKEN_STATIC:
|
||||
case TOKEN_EXTERN:
|
||||
case TOKEN_REGISTER:
|
||||
@ -16,10 +16,10 @@ int peek_decl(struct Parser* parser) {
|
||||
error("not impliment");
|
||||
break;
|
||||
default:
|
||||
flushpeektok(parser);
|
||||
flush_peek_tok(tokbuf);
|
||||
}
|
||||
|
||||
switch (peektoktype(parser)) {
|
||||
switch (peek_tok_type(tokbuf)) {
|
||||
case TOKEN_VOID:
|
||||
case TOKEN_CHAR:
|
||||
case TOKEN_SHORT:
|
||||
@ -27,60 +27,62 @@ int peek_decl(struct Parser* parser) {
|
||||
case TOKEN_LONG:
|
||||
case TOKEN_FLOAT:
|
||||
case TOKEN_DOUBLE:
|
||||
// FIXME Ptr
|
||||
return 1;
|
||||
default:
|
||||
flushpeektok(parser);
|
||||
flush_peek_tok(tokbuf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ASTNode* parse_decl_val(struct Parser* parser) {
|
||||
flushpeektok(parser);
|
||||
// parse_type
|
||||
enum TokenType ttype;
|
||||
struct ASTNode* node;
|
||||
ast_node_t* parse_decl_val(parser_t* parser) {
|
||||
tok_buf_t* tokbuf = &parser->tokbuf;
|
||||
tok_type_t ttype;
|
||||
flush_peek_tok(tokbuf);
|
||||
|
||||
struct ASTNode* type_node = parse_type(parser);
|
||||
struct ASTNode* name_node = parser_ident_without_pop(parser);
|
||||
ast_node_t* node;
|
||||
ast_node_t* type_node = parse_type(parser);
|
||||
flush_peek_tok(tokbuf);
|
||||
ast_node_t* name_node = new_ast_ident_node(peek_tok(tokbuf));
|
||||
|
||||
node = new_ast_node();
|
||||
node->decl_val.type = type_node;
|
||||
node->decl_val.name = name_node;
|
||||
node->type = NT_DECL_VAR;
|
||||
symtab_add_symbol(parser->symtab, name_node->syms.tok.constant.str, node);
|
||||
symtab_add_symbol(parser->symtab, name_node->syms.tok.val.str, node, 0);
|
||||
|
||||
ttype = peektoktype(parser);
|
||||
ttype = peek_tok_type(tokbuf);
|
||||
if (ttype == TOKEN_ASSIGN) {
|
||||
node->decl_val.expr_stmt = parse_stmt(parser);
|
||||
if (node->decl_val.expr_stmt->type != NT_STMT_EXPR) {
|
||||
error("parser_decl_val want stmt_expr");
|
||||
}
|
||||
} else if (ttype == TOKEN_SEMICOLON) {
|
||||
poptok(parser);
|
||||
expecttok(parser, TOKEN_SEMICOLON);
|
||||
pop_tok(tokbuf);
|
||||
expect_pop_tok(tokbuf, TOKEN_SEMICOLON);
|
||||
} else {
|
||||
error("parser_decl_val syntax error");
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// 类型解析入口改进
|
||||
struct ASTNode* parse_decl(struct Parser* parser) {
|
||||
flushpeektok(parser);
|
||||
int idx;
|
||||
enum TokenType ttype;
|
||||
struct ASTNode* node;
|
||||
ast_node_t* parse_decl(parser_t* parser) {
|
||||
tok_buf_t* tokbuf = &parser->tokbuf;
|
||||
flush_peek_tok(tokbuf);
|
||||
tok_type_t ttype;
|
||||
ast_node_t* node;
|
||||
|
||||
if (peek_decl(parser) == 0) {
|
||||
if (peek_decl(tokbuf) == 0) {
|
||||
error("syntax error expect decl_val TYPE");
|
||||
}
|
||||
if (peektoktype(parser) != TOKEN_IDENT) {
|
||||
if (peek_tok_type(tokbuf) != TOKEN_IDENT) {
|
||||
error("syntax error expect decl_val IDENT");
|
||||
}
|
||||
|
||||
ttype = peektoktype(parser);
|
||||
ttype = peek_tok_type(tokbuf);
|
||||
switch (ttype) {
|
||||
case TOKEN_L_PAREN: // (
|
||||
node = parse_func(parser);
|
||||
return NULL;
|
||||
break;
|
||||
case TOKEN_ASSIGN:
|
||||
case TOKEN_SEMICOLON:
|
||||
|
@ -33,14 +33,18 @@ enum ParseType {
|
||||
PREFIX_PARSER,
|
||||
};
|
||||
|
||||
static struct ASTNode *parse_subexpression(struct Parser* parser, enum Precedence prec);
|
||||
static ast_node_t *parse_subexpression(tok_buf_t* tokbuf, symtab_t *symtab, enum Precedence prec);
|
||||
#define NEXT(prec) parse_subexpression(tokbuf, symtab, prec)
|
||||
|
||||
static struct ASTNode* gen_node2(struct ASTNode* left, struct ASTNode* right,
|
||||
enum ASTType type) {
|
||||
struct ASTNode* node = new_ast_node();
|
||||
static ast_node_t* gen_node2(ast_node_t* left, ast_node_t* right,
|
||||
ast_type_t type) {
|
||||
ast_node_t* node = new_ast_node();
|
||||
node->type = type;
|
||||
node->expr.left = left;
|
||||
node->expr.right = right;
|
||||
return node;
|
||||
// FIXME
|
||||
|
||||
// switch (type) {
|
||||
// case NT_ADD : printf("+ \n"); break; // (expr) + (expr)
|
||||
// case NT_SUB : printf("- \n"); break; // (expr) - (expr)
|
||||
@ -68,154 +72,157 @@ static struct ASTNode* gen_node2(struct ASTNode* left, struct ASTNode* right,
|
||||
// }
|
||||
}
|
||||
|
||||
static struct ASTNode* parse_comma(struct Parser* parser, struct ASTNode* left) {
|
||||
struct ASTNode* node = new_ast_node();
|
||||
static ast_node_t* parse_comma(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* left) {
|
||||
ast_node_t* node = new_ast_node();
|
||||
node->type = NT_COMMA;
|
||||
node->expr.left = left;
|
||||
node->expr.right = parse_subexpression(parser, PREC_EXPRESSION);
|
||||
node->expr.right = NEXT(PREC_EXPRESSION);
|
||||
return node;
|
||||
}
|
||||
|
||||
static struct ASTNode* parse_assign(struct Parser* parser, struct ASTNode* left) {
|
||||
flushpeektok(parser);
|
||||
enum TokenType ttype = peektoktype(parser);
|
||||
poptok(parser);
|
||||
struct ASTNode* node = new_ast_node();
|
||||
static ast_node_t* parse_assign(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* left) {
|
||||
flush_peek_tok(tokbuf);
|
||||
tok_type_t ttype = peek_tok_type(tokbuf);
|
||||
pop_tok(tokbuf);
|
||||
ast_node_t* node = new_ast_node();
|
||||
node->type = NT_ASSIGN;
|
||||
// saved left
|
||||
node->expr.left = left;
|
||||
enum Precedence next = PREC_ASSIGNMENT + 1;
|
||||
switch (ttype) {
|
||||
case TOKEN_ASSIGN :
|
||||
left = parse_subexpression(parser, next);
|
||||
left = NEXT(next);
|
||||
break;
|
||||
case TOKEN_ASSIGN_ADD :
|
||||
left = gen_node2(left, parse_subexpression(parser, next), NT_ADD);
|
||||
left = gen_node2(left, NEXT(next), NT_ADD);
|
||||
break;
|
||||
case TOKEN_ASSIGN_SUB :
|
||||
left = gen_node2(left, parse_subexpression(parser, next), NT_SUB);
|
||||
left = gen_node2(left, NEXT(next), NT_SUB);
|
||||
break;
|
||||
case TOKEN_ASSIGN_MUL :
|
||||
left = gen_node2(left, parse_subexpression(parser, next), NT_MUL);
|
||||
left = gen_node2(left, NEXT(next), NT_MUL);
|
||||
break;
|
||||
case TOKEN_ASSIGN_DIV :
|
||||
left = gen_node2(left, parse_subexpression(parser, next), NT_DIV);
|
||||
left = gen_node2(left, NEXT(next), NT_DIV);
|
||||
break;
|
||||
case TOKEN_ASSIGN_MOD :
|
||||
left = gen_node2(left, parse_subexpression(parser, next), NT_MOD);
|
||||
left = gen_node2(left, NEXT(next), NT_MOD);
|
||||
break;
|
||||
case TOKEN_ASSIGN_L_SH :
|
||||
left = gen_node2(left, parse_subexpression(parser, next), NT_L_SH);
|
||||
left = gen_node2(left, NEXT(next), NT_L_SH);
|
||||
break;
|
||||
case TOKEN_ASSIGN_R_SH :
|
||||
left = gen_node2(left, parse_subexpression(parser, next), NT_R_SH);
|
||||
left = gen_node2(left, NEXT(next), NT_R_SH);
|
||||
break;
|
||||
case TOKEN_ASSIGN_AND :
|
||||
left = gen_node2(left, parse_subexpression(parser, next), NT_AND);
|
||||
left = gen_node2(left, NEXT(next), NT_AND);
|
||||
break;
|
||||
case TOKEN_ASSIGN_OR :
|
||||
left = gen_node2(left, parse_subexpression(parser, next), NT_OR);
|
||||
left = gen_node2(left, NEXT(next), NT_OR);
|
||||
break;
|
||||
case TOKEN_ASSIGN_XOR :
|
||||
left = gen_node2(left, parse_subexpression(parser, next), NT_XOR);
|
||||
left = gen_node2(left, NEXT(next), NT_XOR);
|
||||
break;
|
||||
default:
|
||||
error("unsupported operator");
|
||||
break;
|
||||
}
|
||||
node->expr.right = left;
|
||||
return node;
|
||||
}
|
||||
|
||||
static struct ASTNode* parse_cmp(struct Parser* parser, struct ASTNode* left) {
|
||||
flushpeektok(parser);
|
||||
enum TokenType ttype = peektoktype(parser);
|
||||
poptok(parser);
|
||||
struct ASTNode* node = new_ast_node();
|
||||
static ast_node_t* parse_cmp(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* left) {
|
||||
flush_peek_tok(tokbuf);
|
||||
tok_type_t ttype = peek_tok_type(tokbuf);
|
||||
pop_tok(tokbuf);
|
||||
ast_node_t* node = new_ast_node();
|
||||
// saved left
|
||||
node->expr.left = left;
|
||||
switch (ttype) {
|
||||
case TOKEN_EQ:
|
||||
node->type = NT_EQ;
|
||||
node->expr.right = parse_subexpression(parser, PREC_EQUALITY);
|
||||
node->expr.right = NEXT(PREC_EQUALITY);
|
||||
break;
|
||||
case TOKEN_NEQ:
|
||||
node->type = NT_NEQ;
|
||||
node->expr.right = parse_subexpression(parser, PREC_EQUALITY);
|
||||
node->expr.right = NEXT(PREC_EQUALITY);
|
||||
break;
|
||||
case TOKEN_LT:
|
||||
node->type = NT_LT;
|
||||
node->expr.right = parse_subexpression(parser, PREC_RELATIONAL);
|
||||
node->expr.right = NEXT(PREC_RELATIONAL);
|
||||
break;
|
||||
case TOKEN_GT:
|
||||
node->type = NT_GT;
|
||||
node->expr.right = parse_subexpression(parser, PREC_RELATIONAL);
|
||||
node->expr.right = NEXT(PREC_RELATIONAL);
|
||||
break;
|
||||
case TOKEN_LE:
|
||||
node->type = NT_LE;
|
||||
node->expr.right = parse_subexpression(parser, PREC_RELATIONAL);
|
||||
node->expr.right = NEXT(PREC_RELATIONAL);
|
||||
break;
|
||||
case TOKEN_GE:
|
||||
node->type = NT_GE;
|
||||
node->expr.right = parse_subexpression(parser, PREC_RELATIONAL);
|
||||
node->expr.right = NEXT(PREC_RELATIONAL);
|
||||
break;
|
||||
default:
|
||||
error("invalid operator");
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
static struct ASTNode* parse_cal(struct Parser* parser, struct ASTNode* left) {
|
||||
flushpeektok(parser);
|
||||
enum TokenType ttype = peektoktype(parser);
|
||||
poptok(parser);
|
||||
struct ASTNode* node = new_ast_node();
|
||||
static ast_node_t* parse_cal(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* left) {
|
||||
flush_peek_tok(tokbuf);
|
||||
tok_type_t ttype = peek_tok_type(tokbuf);
|
||||
pop_tok(tokbuf);
|
||||
ast_node_t* node = new_ast_node();
|
||||
node->expr.left = left;
|
||||
switch (ttype) {
|
||||
case TOKEN_OR_OR:
|
||||
node->type = NT_OR_OR;
|
||||
node->expr.right = parse_subexpression(parser, PREC_LOGICAL_OR);
|
||||
node->expr.right = NEXT(PREC_LOGICAL_OR);
|
||||
break;
|
||||
case TOKEN_AND_AND:
|
||||
node->type = NT_AND_AND;
|
||||
node->expr.right = parse_subexpression(parser, PREC_LOGICAL_AND);
|
||||
node->expr.right = NEXT(PREC_LOGICAL_AND);
|
||||
break;
|
||||
case TOKEN_OR:
|
||||
node->type = NT_OR;
|
||||
node->expr.right = parse_subexpression(parser, PREC_OR);
|
||||
node->expr.right = NEXT(PREC_OR);
|
||||
break;
|
||||
case TOKEN_XOR:
|
||||
node->type = NT_XOR;
|
||||
node->expr.right = parse_subexpression(parser, PREC_XOR);
|
||||
node->expr.right = NEXT(PREC_XOR);
|
||||
break;
|
||||
case TOKEN_AND:
|
||||
node->type = NT_AND;
|
||||
node->expr.right = parse_subexpression(parser, PREC_AND);
|
||||
node->expr.right = NEXT(PREC_AND);
|
||||
break;
|
||||
case TOKEN_L_SH:
|
||||
node->type = NT_L_SH;
|
||||
node->expr.right = parse_subexpression(parser, PREC_SHIFT);
|
||||
node->expr.right = NEXT(PREC_SHIFT);
|
||||
break;
|
||||
case TOKEN_R_SH:
|
||||
node->type = NT_R_SH;
|
||||
node->expr.right = parse_subexpression(parser, PREC_SHIFT);
|
||||
node->expr.right = NEXT(PREC_SHIFT);
|
||||
break;
|
||||
case TOKEN_ADD:
|
||||
node->type = NT_ADD;
|
||||
node->expr.right = parse_subexpression(parser, PREC_ADDITIVE);
|
||||
node->expr.right = NEXT(PREC_ADDITIVE);
|
||||
break;
|
||||
case TOKEN_SUB:
|
||||
node->type = NT_SUB;
|
||||
node->expr.right = parse_subexpression(parser, PREC_ADDITIVE);
|
||||
node->expr.right = NEXT(PREC_ADDITIVE);
|
||||
break;
|
||||
case TOKEN_MUL:
|
||||
node->type = NT_MUL;
|
||||
node->expr.right = parse_subexpression(parser, PREC_MULTIPLICATIVE);
|
||||
node->expr.right = NEXT(PREC_MULTIPLICATIVE);
|
||||
break;
|
||||
case TOKEN_DIV:
|
||||
node->type = NT_DIV;
|
||||
node->expr.right = parse_subexpression(parser, PREC_MULTIPLICATIVE);
|
||||
node->expr.right = NEXT(PREC_MULTIPLICATIVE);
|
||||
break;
|
||||
case TOKEN_MOD:
|
||||
node->type = NT_MOD;
|
||||
node->expr.right = parse_subexpression(parser, PREC_MULTIPLICATIVE);
|
||||
node->expr.right = NEXT(PREC_MULTIPLICATIVE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -223,44 +230,50 @@ static struct ASTNode* parse_cal(struct Parser* parser, struct ASTNode* left) {
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
// 新增函数调用解析
|
||||
static struct ASTNode* parse_call(struct Parser* parser, struct ASTNode* ident) {
|
||||
struct ASTNode* node = new_ast_node();
|
||||
static ast_node_t* parse_call(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* ident) {
|
||||
ast_node_t* node = new_ast_node();
|
||||
node->type = NT_TERM_CALL;
|
||||
poptok(parser); // 跳过 '('
|
||||
node->call.name = ident;
|
||||
node->call.params = new_ast_node();
|
||||
vector_init(node->call.params->params.params);
|
||||
pop_tok(tokbuf); // 跳过 '('
|
||||
|
||||
enum TokenType ttype;
|
||||
// 解析参数列表
|
||||
while ((ttype = peektoktype(parser)) != TOKEN_R_PAREN) {
|
||||
// add_arg(node, parse_expr(parser));
|
||||
if (ttype == TOKEN_COMMA) poptok(parser);
|
||||
else poptok(parser);
|
||||
tok_type_t ttype;
|
||||
while (1) {
|
||||
flush_peek_tok(tokbuf);
|
||||
ttype = peek_tok_type(tokbuf);
|
||||
if (ttype == TOKEN_R_PAREN) {
|
||||
break;
|
||||
}
|
||||
ast_node_t* param = NEXT(PREC_EXPRESSION);
|
||||
vector_push(node->call.params->params.params, param);
|
||||
flush_peek_tok(tokbuf);
|
||||
ttype = peek_tok_type(tokbuf);
|
||||
if (ttype == TOKEN_COMMA) pop_tok(tokbuf);
|
||||
}
|
||||
poptok(parser); // 跳过 ')'
|
||||
pop_tok(tokbuf); // 跳过 ')'
|
||||
|
||||
char* name = ident->syms.tok.constant.str;
|
||||
void* sym = symtab_lookup_symbol(parser->symtab, name);
|
||||
if (sym == NULL) {
|
||||
const char* name = ident->syms.tok.val.str;
|
||||
ast_node_t* sym = symtab_lookup_symbol(symtab, name);
|
||||
// TODO check func is match
|
||||
if (sym == NULL || sym->type != NT_DECL_FUNC) {
|
||||
error("function not decl %s", name);
|
||||
}
|
||||
node->call.name = name;
|
||||
node->call.params = NULL;
|
||||
node->call.name = ident;
|
||||
node->call.func_decl = sym;
|
||||
return node;
|
||||
}
|
||||
|
||||
static struct ASTNode* parse_paren(struct Parser* parser, struct ASTNode* left) {
|
||||
flushpeektok(parser);
|
||||
enum TokenType ttype;
|
||||
expecttok(parser, TOKEN_L_PAREN);
|
||||
left = parse_subexpression(parser, PREC_EXPRESSION);
|
||||
flushpeektok(parser);
|
||||
expecttok(parser, TOKEN_R_PAREN);
|
||||
static ast_node_t* parse_paren(tok_buf_t* tokbuf, symtab_t *symtab, ast_node_t* left) {
|
||||
flush_peek_tok(tokbuf);
|
||||
expect_pop_tok(tokbuf, TOKEN_L_PAREN);
|
||||
left = NEXT(PREC_EXPRESSION);
|
||||
flush_peek_tok(tokbuf);
|
||||
expect_pop_tok(tokbuf, TOKEN_R_PAREN);
|
||||
return left;
|
||||
}
|
||||
|
||||
typedef struct ASTNode* (*parse_expr_fun_t)(struct Parser*, struct ASTNode*);
|
||||
typedef ast_node_t* (*parse_expr_fun_t)(tok_buf_t*, symtab_t* , ast_node_t*);
|
||||
static struct expr_prec_table_t {
|
||||
parse_expr_fun_t parser;
|
||||
enum Precedence prec;
|
||||
@ -309,11 +322,11 @@ static struct expr_prec_table_t {
|
||||
[TOKEN_L_PAREN] = {parse_paren, PREC_POSTFIX, INFIX_PARSER},
|
||||
};
|
||||
|
||||
static struct ASTNode *parse_primary_expression(struct Parser* parser) {
|
||||
flushpeektok(parser);
|
||||
static ast_node_t *parse_primary_expression(tok_buf_t* tokbuf, symtab_t *symtab) {
|
||||
flush_peek_tok(tokbuf);
|
||||
|
||||
struct Token* tok = peektok(parser);
|
||||
struct ASTNode *node = new_ast_node();
|
||||
tok_t* tok = peek_tok(tokbuf);
|
||||
ast_node_t *node = new_ast_node();
|
||||
node->type = NT_TERM_VAL;
|
||||
node->syms.tok = *tok;
|
||||
|
||||
@ -330,34 +343,35 @@ static struct ASTNode *parse_primary_expression(struct Parser* parser) {
|
||||
case TOKEN_STRING_LITERAL:
|
||||
// node->data.data_type = TYPE_POINTER;
|
||||
case TOKEN_IDENT:
|
||||
node = parse_ident(parser);
|
||||
if (peektoktype(parser) == TOKEN_L_PAREN) {
|
||||
node = parse_call(parser, node);
|
||||
node = expect_pop_ident(tokbuf);
|
||||
tok_type_t ttype = peek_tok_type(tokbuf);
|
||||
if (ttype == TOKEN_L_PAREN) {
|
||||
node = parse_call(tokbuf, symtab, node);
|
||||
} else {
|
||||
void *sym = symtab_lookup_symbol(parser->symtab, tok->constant.str);
|
||||
void *sym = symtab_lookup_symbol(symtab, tok->val.str);
|
||||
if (sym == NULL) {
|
||||
error("undefined symbol but use %s", tok->constant.str);
|
||||
error("undefined symbol but use %s", tok->val.str);
|
||||
}
|
||||
node->type = NT_TERM_IDENT;
|
||||
node->syms.decl_node = sym;
|
||||
goto END;
|
||||
}
|
||||
goto END;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
poptok(parser);
|
||||
pop_tok(tokbuf);
|
||||
END:
|
||||
return node;
|
||||
}
|
||||
|
||||
static struct ASTNode *parse_subexpression(struct Parser* parser, enum Precedence prec) {
|
||||
enum TokenType ttype;
|
||||
struct expr_prec_table_t* work;
|
||||
struct ASTNode* left;
|
||||
static ast_node_t *parse_subexpression(tok_buf_t* tokbuf, symtab_t *symtab, enum Precedence prec) {
|
||||
tok_type_t ttype;
|
||||
struct expr_prec_table_t* work;
|
||||
ast_node_t* left;
|
||||
|
||||
while (1) {
|
||||
flushpeektok(parser);
|
||||
ttype = peektoktype(parser);
|
||||
flush_peek_tok(tokbuf);
|
||||
ttype = peek_tok_type(tokbuf);
|
||||
work = &expr_table[ttype];
|
||||
// FIXME
|
||||
if (ttype == TOKEN_SEMICOLON || ttype == TOKEN_R_PAREN) {
|
||||
@ -365,16 +379,16 @@ static struct ASTNode *parse_subexpression(struct Parser* parser, enum Precedenc
|
||||
}
|
||||
if (work == NULL || work->parser == NULL || work->ptype == PREFIX_PARSER) {
|
||||
if (work->parser != NULL) {
|
||||
left = work->parser(parser, NULL);
|
||||
left = work->parser(tokbuf, symtab, NULL);
|
||||
} else {
|
||||
left = parse_primary_expression(parser);
|
||||
left = parse_primary_expression(tokbuf, symtab);
|
||||
}
|
||||
} else if (work->ptype == INFIX_PARSER) {
|
||||
if (work->parser == NULL)
|
||||
break;
|
||||
if (work->prec <= prec)
|
||||
break;
|
||||
left = work->parser(parser, left);
|
||||
left = work->parser(tokbuf, symtab, left);
|
||||
}
|
||||
// assert(left != NULL);
|
||||
}
|
||||
@ -382,9 +396,11 @@ static struct ASTNode *parse_subexpression(struct Parser* parser, enum Precedenc
|
||||
return left;
|
||||
}
|
||||
|
||||
struct ASTNode* parse_expr(struct Parser* parser) {
|
||||
flushpeektok(parser);
|
||||
enum TokenType ttype = peektoktype(parser);
|
||||
ast_node_t* parse_expr(parser_t* parser) {
|
||||
tok_buf_t* tokbuf = &(parser->tokbuf);
|
||||
symtab_t *symtab = parser->symtab;
|
||||
flush_peek_tok(tokbuf);
|
||||
tok_type_t ttype = peek_tok_type(tokbuf);
|
||||
switch (ttype) {
|
||||
case TOKEN_NOT:
|
||||
case TOKEN_AND:
|
||||
@ -401,9 +417,9 @@ struct ASTNode* parse_expr(struct Parser* parser) {
|
||||
case TOKEN_SUB_SUB:
|
||||
case TOKEN_SIZEOF:
|
||||
case TOKEN_IDENT:
|
||||
return parse_subexpression(parser, PREC_EXPRESSION);
|
||||
return NEXT(PREC_EXPRESSION);
|
||||
default:
|
||||
error("Want expr but not got %s", get_token_name(ttype));
|
||||
error("Want expr but not got %s", get_tok_name(ttype));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -6,34 +6,21 @@
|
||||
#define FUNC_PARAM_CACHE_SIZE 32 // 合理初始值,可覆盖99%常见情况
|
||||
#endif
|
||||
|
||||
struct FuncParamCache {
|
||||
struct Token tokens[FUNC_PARAM_CACHE_SIZE];
|
||||
int read_pos; // 当前读取位置
|
||||
int write_pos; // 写入位置
|
||||
int depth; // 当前缓存深度
|
||||
};
|
||||
|
||||
static enum TokenType peekcachetype(struct FuncParamCache* cache) {
|
||||
return cache->tokens[cache->read_pos++].type;
|
||||
}
|
||||
|
||||
// TODO 语义分析压入符号表
|
||||
static void parse_params(struct Parser* parser, struct FuncParamCache* cache, struct ASTNode* node) {
|
||||
// = peekcachetype(cache);
|
||||
enum TokenType ttype;
|
||||
// if (ttype != TOKEN_L_PAREN) {
|
||||
// error("function expected '('\n");
|
||||
// }
|
||||
struct ASTNode *params = new_ast_node();
|
||||
node->func.params = params;
|
||||
int params_size = 0;
|
||||
static void parse_params(parser_t* parser, tok_buf_t* cache, ast_node_t* node) {
|
||||
tok_type_t ttype;
|
||||
ast_node_t *params = new_ast_node();
|
||||
node->decl_func.params = params;
|
||||
vector_init(params->params.params);
|
||||
|
||||
while ((ttype = peekcachetype(cache)) != TOKEN_R_PAREN) {
|
||||
int depth = 1;
|
||||
while (depth) {
|
||||
ttype = peek_tok_type(cache);
|
||||
switch (ttype) {
|
||||
case TOKEN_COMMA:
|
||||
break;
|
||||
case TOKEN_ELLIPSIS:
|
||||
ttype = peekcachetype(cache);
|
||||
ttype = peek_tok_type(cache);
|
||||
if (ttype != TOKEN_R_PAREN) {
|
||||
error("... must be a last parameter list (expect ')')");
|
||||
}
|
||||
@ -41,9 +28,29 @@ static void parse_params(struct Parser* parser, struct FuncParamCache* cache, st
|
||||
error("not implement");
|
||||
break;
|
||||
case TOKEN_IDENT:
|
||||
params->children[params_size++] = NULL;
|
||||
// TODO 静态数组
|
||||
flush_peek_tok(cache);
|
||||
ast_node_t* id_node = new_ast_ident_node(peek_tok(cache));
|
||||
ast_node_t* node = new_ast_node();
|
||||
node->type = NT_DECL_VAR;
|
||||
node->decl_val.name = id_node;
|
||||
// TODO typing sys
|
||||
node->decl_val.type = NULL;
|
||||
node->decl_val.expr_stmt = NULL;
|
||||
node->decl_val.data = NULL;
|
||||
vector_push(params->params.params, node);
|
||||
symtab_add_symbol(parser->symtab, id_node->syms.tok.val.str, node, 0);
|
||||
break;
|
||||
case TOKEN_L_PAREN: {
|
||||
depth++;
|
||||
break;
|
||||
}
|
||||
case TOKEN_R_PAREN: {
|
||||
depth--;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
// TODO 使用cache的类型解析
|
||||
// parse_type(parser);
|
||||
// TODO type parse
|
||||
@ -51,39 +58,42 @@ static void parse_params(struct Parser* parser, struct FuncParamCache* cache, st
|
||||
// ttype = peekcachetype(cache);
|
||||
// if (ttype != TOKEN_IDENT) {
|
||||
// node->node_type = NT_DECL_FUNC;
|
||||
// flushpeektok(parser);
|
||||
// flush_peek_tok(tokbuf);
|
||||
// continue;
|
||||
// }
|
||||
// error("function expected ')' or ','\n");
|
||||
}
|
||||
pop_tok(cache);
|
||||
}
|
||||
}
|
||||
|
||||
enum ASTType check_is_func_decl(struct Parser* parser, struct FuncParamCache* cache) {
|
||||
cache->depth = 1;
|
||||
cache->read_pos = 0;
|
||||
cache->write_pos = 0;
|
||||
ast_type_t check_is_func_decl(tok_buf_t* tokbuf, tok_buf_t* cache) {
|
||||
expect_pop_tok(tokbuf, TOKEN_L_PAREN);
|
||||
int depth = 1;
|
||||
|
||||
while (cache->depth) {
|
||||
struct Token* tok = peektok(parser);
|
||||
poptok(parser);
|
||||
if (cache->write_pos >= FUNC_PARAM_CACHE_SIZE - 1) {
|
||||
while (depth) {
|
||||
tok_t* tok = peek_tok(tokbuf);
|
||||
pop_tok(tokbuf);
|
||||
if (cache->size >= cache->cap - 1) {
|
||||
error("function parameter list too long");
|
||||
}
|
||||
cache->tokens[cache->write_pos++] = *tok;
|
||||
cache->buf[cache->size++] = *tok;
|
||||
switch (tok->type) {
|
||||
case TOKEN_L_PAREN:
|
||||
cache->depth++;
|
||||
depth++;
|
||||
break;
|
||||
case TOKEN_R_PAREN:
|
||||
cache->depth--;
|
||||
depth--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
cache->end = cache->size;
|
||||
|
||||
switch (peektoktype(parser)) {
|
||||
switch (peek_tok_type(tokbuf)) {
|
||||
case TOKEN_SEMICOLON:
|
||||
poptok(parser);
|
||||
pop_tok(tokbuf);
|
||||
return NT_DECL_FUNC;
|
||||
case TOKEN_L_BRACE:
|
||||
return NT_FUNC;
|
||||
@ -93,28 +103,66 @@ enum ASTType check_is_func_decl(struct Parser* parser, struct FuncParamCache* ca
|
||||
}
|
||||
}
|
||||
|
||||
struct ASTNode* parse_func(struct Parser* parser) {
|
||||
struct ASTNode* ret_type = parse_type(parser);
|
||||
struct ASTNode* func_name = parse_ident(parser);
|
||||
static ast_node_t* new_ast_node_funcdecl(ast_node_t* ret, ast_node_t* name) {
|
||||
ast_node_t* node = new_ast_node();
|
||||
node->type = NT_DECL_FUNC;
|
||||
node->decl_func.ret = ret;
|
||||
node->decl_func.name = name;
|
||||
node->decl_func.def = NULL;
|
||||
return node;
|
||||
}
|
||||
|
||||
struct ASTNode* node = new_ast_node();
|
||||
node->func.ret = ret_type;
|
||||
node->func.name = func_name;
|
||||
void parse_func(parser_t* parser) {
|
||||
tok_buf_t* tokbuf = &(parser->tokbuf);
|
||||
flush_peek_tok(tokbuf);
|
||||
ast_node_t* ret_node = parse_type(parser);
|
||||
ast_node_t* name_node = expect_pop_ident(tokbuf);
|
||||
const char* func_name = name_node->syms.tok.val.str;
|
||||
ast_node_t* decl = new_ast_node_funcdecl(ret_node, name_node);
|
||||
|
||||
flushpeektok(parser);
|
||||
expecttok(parser, TOKEN_L_PAREN);
|
||||
struct FuncParamCache cache;
|
||||
node->type = check_is_func_decl(parser, &cache);
|
||||
tok_buf_t cache;
|
||||
init_tokbuf(&cache, NULL, NULL);
|
||||
cache.cap = FUNC_PARAM_CACHE_SIZE;
|
||||
tok_t buf[FUNC_PARAM_CACHE_SIZE];
|
||||
cache.buf = buf;
|
||||
|
||||
ast_type_t type = check_is_func_decl(&(parser->tokbuf), &cache);
|
||||
|
||||
symtab_add_symbol(parser->symtab, func_name->syms.tok.constant.str, node);
|
||||
if (node->type == NT_DECL_FUNC) {
|
||||
return node;
|
||||
ast_node_t* prev = symtab_add_symbol(parser->symtab, func_name, decl, 1);
|
||||
if (prev != NULL) {
|
||||
if (prev->type != NT_DECL_FUNC) {
|
||||
error("the symbol duplicate old is %d, new is func", prev->type);
|
||||
}
|
||||
// TODO check redeclare func is match
|
||||
if (type == NT_FUNC) {
|
||||
// TODO Free decl;
|
||||
free(decl);
|
||||
decl = prev;
|
||||
goto FUNC;
|
||||
}
|
||||
return;
|
||||
}
|
||||
vector_push(parser->root->root.children, decl);
|
||||
if (type == NT_DECL_FUNC) {
|
||||
return;
|
||||
}
|
||||
|
||||
FUNC:
|
||||
// 该data临时用于判断是否重复定义
|
||||
if (decl->decl_func.def != NULL) {
|
||||
error("redefinition of function %s", func_name);
|
||||
}
|
||||
|
||||
ast_node_t* node = new_ast_node();
|
||||
node->type = NT_FUNC;
|
||||
node->func.decl = decl;
|
||||
node->func.data = NULL;
|
||||
|
||||
decl->decl_func.def = node;
|
||||
symtab_enter_scope(parser->symtab);
|
||||
parse_params(parser, &cache, node);
|
||||
parse_params(parser, &cache, decl);
|
||||
node->func.body = parse_block(parser);
|
||||
symtab_leave_scope(parser->symtab);
|
||||
|
||||
return node;
|
||||
vector_push(parser->root->root.children, node);
|
||||
}
|
||||
|
@ -5,25 +5,30 @@
|
||||
#define PROG_MAX_NODE_SIZE (1024 * 4)
|
||||
#endif
|
||||
|
||||
void parse_prog(struct Parser* parser) {
|
||||
void parse_func(parser_t* parser);
|
||||
|
||||
void parse_prog(parser_t* parser) {
|
||||
/**
|
||||
* Program := (Declaration | Definition)*
|
||||
* same as
|
||||
* Program := Declaration* Definition*
|
||||
*/
|
||||
int child_size = 0;
|
||||
tok_buf_t *tokbuf = &(parser->tokbuf);
|
||||
parser->root = new_ast_node();
|
||||
struct ASTNode* node;
|
||||
parser->root->root.children = xmalloc(sizeof(struct ASTNode*) * PROG_MAX_NODE_SIZE);
|
||||
ast_node_t* node;
|
||||
parser->root->type = NT_ROOT;
|
||||
vector_init(parser->root->root.children);
|
||||
while (1) {
|
||||
flushpeektok(parser);
|
||||
if (peektoktype(parser) == TOKEN_EOF) {
|
||||
flush_peek_tok(tokbuf);
|
||||
if (peek_tok_type(tokbuf) == TOKEN_EOF) {
|
||||
break;
|
||||
}
|
||||
node = parse_decl(parser);
|
||||
parser->root->root.children[child_size++] = node;
|
||||
if (node == NULL) {
|
||||
parse_func(parser);
|
||||
} else {
|
||||
vector_push(parser->root->root.children, node);
|
||||
}
|
||||
}
|
||||
parser->root->type = NT_ROOT;
|
||||
parser->root->root.child_size = child_size;
|
||||
return;
|
||||
}
|
||||
|
@ -1,27 +1,28 @@
|
||||
#include "../parser.h"
|
||||
#include "ast.h"
|
||||
|
||||
struct ASTNode* parse_stmt(struct Parser* parser) {
|
||||
flushpeektok(parser);
|
||||
enum TokenType ttype = peektoktype(parser);
|
||||
struct ASTNode* node = new_ast_node();
|
||||
ast_node_t* parse_stmt(parser_t* parser) {
|
||||
tok_buf_t* tokbuf = &parser->tokbuf;
|
||||
flush_peek_tok(tokbuf);
|
||||
tok_type_t ttype = peek_tok_type(tokbuf);
|
||||
ast_node_t* node = new_ast_node();
|
||||
switch (ttype) {
|
||||
case TOKEN_IF: {
|
||||
/**
|
||||
* if (exp) stmt
|
||||
* if (exp) stmt else stmt
|
||||
*/
|
||||
poptok(parser);
|
||||
pop_tok(tokbuf);
|
||||
|
||||
expecttok(parser, TOKEN_L_PAREN);
|
||||
expect_pop_tok(tokbuf, TOKEN_L_PAREN);
|
||||
node->if_stmt.cond = parse_expr(parser);
|
||||
flushpeektok(parser);
|
||||
expecttok(parser, TOKEN_R_PAREN);
|
||||
flush_peek_tok(tokbuf);
|
||||
expect_pop_tok(tokbuf, TOKEN_R_PAREN);
|
||||
|
||||
node->if_stmt.if_stmt = parse_stmt(parser);
|
||||
ttype = peektoktype(parser);
|
||||
ttype = peek_tok_type(tokbuf);
|
||||
if (ttype == TOKEN_ELSE) {
|
||||
poptok(parser);
|
||||
pop_tok(tokbuf);
|
||||
node->if_stmt.else_stmt = parse_stmt(parser);
|
||||
} else {
|
||||
node->if_stmt.else_stmt = NULL;
|
||||
@ -33,11 +34,11 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
|
||||
/**
|
||||
* switch (exp) stmt
|
||||
*/
|
||||
poptok(parser);
|
||||
pop_tok(tokbuf);
|
||||
|
||||
expecttok(parser, TOKEN_L_PAREN);
|
||||
expect_pop_tok(tokbuf, TOKEN_L_PAREN);
|
||||
node->switch_stmt.cond = parse_expr(parser);
|
||||
expecttok(parser, TOKEN_R_PAREN);
|
||||
expect_pop_tok(tokbuf, TOKEN_R_PAREN);
|
||||
|
||||
node->switch_stmt.body = parse_stmt(parser);
|
||||
node->type = NT_STMT_SWITCH;
|
||||
@ -47,11 +48,11 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
|
||||
/**
|
||||
* while (exp) stmt
|
||||
*/
|
||||
poptok(parser);
|
||||
pop_tok(tokbuf);
|
||||
|
||||
expecttok(parser, TOKEN_L_PAREN);
|
||||
expect_pop_tok(tokbuf, TOKEN_L_PAREN);
|
||||
node->while_stmt.cond = parse_expr(parser);
|
||||
expecttok(parser, TOKEN_R_PAREN);
|
||||
expect_pop_tok(tokbuf, TOKEN_R_PAREN);
|
||||
|
||||
node->while_stmt.body = parse_stmt(parser);
|
||||
node->type = NT_STMT_WHILE;
|
||||
@ -61,16 +62,16 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
|
||||
/**
|
||||
* do stmt while (exp)
|
||||
*/
|
||||
poptok(parser);
|
||||
pop_tok(tokbuf);
|
||||
node->do_while_stmt.body = parse_stmt(parser);
|
||||
ttype = peektoktype(parser);
|
||||
ttype = peek_tok_type(tokbuf);
|
||||
if (ttype != TOKEN_WHILE) {
|
||||
error("expected while after do");
|
||||
}
|
||||
poptok(parser);
|
||||
expecttok(parser, TOKEN_L_PAREN);
|
||||
pop_tok(tokbuf);
|
||||
expect_pop_tok(tokbuf, TOKEN_L_PAREN);
|
||||
node->do_while_stmt.cond = parse_expr(parser);
|
||||
expecttok(parser, TOKEN_R_PAREN);
|
||||
expect_pop_tok(tokbuf, TOKEN_R_PAREN);
|
||||
node->type = NT_STMT_DOWHILE;
|
||||
break;
|
||||
}
|
||||
@ -79,36 +80,36 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
|
||||
* for (init; [cond]; [iter]) stmt
|
||||
*/
|
||||
// node->children.stmt.for_stmt.init
|
||||
poptok(parser);
|
||||
ttype = peektoktype(parser);
|
||||
pop_tok(tokbuf);
|
||||
ttype = peek_tok_type(tokbuf);
|
||||
if (ttype != TOKEN_L_PAREN) {
|
||||
error("expected ( after for");
|
||||
}
|
||||
poptok(parser);
|
||||
pop_tok(tokbuf);
|
||||
|
||||
// init expr or init decl_var
|
||||
// TODO need add this feature
|
||||
node->for_stmt.init = parse_expr(parser);
|
||||
expecttok(parser, TOKEN_SEMICOLON);
|
||||
expect_pop_tok(tokbuf, TOKEN_SEMICOLON);
|
||||
|
||||
// cond expr or null
|
||||
ttype = peektoktype(parser);
|
||||
ttype = peek_tok_type(tokbuf);
|
||||
if (ttype != TOKEN_SEMICOLON) {
|
||||
node->for_stmt.cond = parse_expr(parser);
|
||||
expecttok(parser, TOKEN_SEMICOLON);
|
||||
expect_pop_tok(tokbuf, TOKEN_SEMICOLON);
|
||||
} else {
|
||||
node->for_stmt.cond = NULL;
|
||||
poptok(parser);
|
||||
pop_tok(tokbuf);
|
||||
}
|
||||
|
||||
// iter expr or null
|
||||
ttype = peektoktype(parser);
|
||||
ttype = peek_tok_type(tokbuf);
|
||||
if (ttype != TOKEN_R_PAREN) {
|
||||
node->for_stmt.iter = parse_expr(parser);
|
||||
expecttok(parser, TOKEN_R_PAREN);
|
||||
expect_pop_tok(tokbuf, TOKEN_R_PAREN);
|
||||
} else {
|
||||
node->for_stmt.iter = NULL;
|
||||
poptok(parser);
|
||||
pop_tok(tokbuf);
|
||||
}
|
||||
|
||||
node->for_stmt.body = parse_stmt(parser);
|
||||
@ -120,8 +121,8 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
|
||||
* break ;
|
||||
*/
|
||||
// TODO check 导致外围 for、while 或 do-while 循环或 switch 语句终止。
|
||||
poptok(parser);
|
||||
expecttok(parser, TOKEN_SEMICOLON);
|
||||
pop_tok(tokbuf);
|
||||
expect_pop_tok(tokbuf, TOKEN_SEMICOLON);
|
||||
|
||||
node->type = NT_STMT_BREAK;
|
||||
break;
|
||||
@ -131,8 +132,8 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
|
||||
* continue ;
|
||||
*/
|
||||
// TODO check 导致跳过整个 for、 while 或 do-while 循环体的剩余部分。
|
||||
poptok(parser);
|
||||
expecttok(parser, TOKEN_SEMICOLON);
|
||||
pop_tok(tokbuf);
|
||||
expect_pop_tok(tokbuf, TOKEN_SEMICOLON);
|
||||
|
||||
node->type = NT_STMT_CONTINUE;
|
||||
break;
|
||||
@ -142,16 +143,16 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
|
||||
* return [exp] ;
|
||||
*/
|
||||
// TODO 终止当前函数并返回指定值给调用方函数。
|
||||
poptok(parser);
|
||||
ttype = peektoktype(parser);
|
||||
pop_tok(tokbuf);
|
||||
ttype = peek_tok_type(tokbuf);
|
||||
if (ttype != TOKEN_SEMICOLON) {
|
||||
node->return_stmt.expr_stmt = parse_expr(parser);
|
||||
flushpeektok(parser);
|
||||
expecttok(parser, TOKEN_SEMICOLON);
|
||||
flush_peek_tok(tokbuf);
|
||||
expect_pop_tok(tokbuf, TOKEN_SEMICOLON);
|
||||
} else {
|
||||
node->return_stmt.expr_stmt = NULL;
|
||||
pop_tok(tokbuf);
|
||||
}
|
||||
poptok(parser);
|
||||
node->type = NT_STMT_RETURN;
|
||||
break;
|
||||
}
|
||||
@ -161,15 +162,15 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
|
||||
*/
|
||||
// TODO check label 将控制无条件转移到所欲位置。
|
||||
//在无法用约定的构造将控制转移到所欲位置时使用。
|
||||
poptok(parser);
|
||||
pop_tok(tokbuf);
|
||||
// find symbol table
|
||||
ttype = peektoktype(parser);
|
||||
ttype = peek_tok_type(tokbuf);
|
||||
if (ttype != TOKEN_IDENT) {
|
||||
error("expect identifier after goto");
|
||||
}
|
||||
expecttok(parser, TOKEN_SEMICOLON);
|
||||
expect_pop_tok(tokbuf, TOKEN_SEMICOLON);
|
||||
// TODO filling label
|
||||
node->goto_stmt.label = parse_ident(parser);
|
||||
node->goto_stmt.label = expect_pop_ident(tokbuf);
|
||||
node->type = NT_STMT_GOTO;
|
||||
break;
|
||||
}
|
||||
@ -181,7 +182,7 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
|
||||
* if () ;
|
||||
* for () ;
|
||||
*/
|
||||
poptok(parser);
|
||||
pop_tok(tokbuf);
|
||||
node->type = NT_STMT_EMPTY;
|
||||
break;
|
||||
}
|
||||
@ -193,30 +194,30 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
|
||||
node->type = NT_STMT_BLOCK;
|
||||
break;
|
||||
}
|
||||
case TOKEN_IDENT: {
|
||||
case TOKEN_IDENT: {
|
||||
// TODO label goto
|
||||
if (peektoktype(parser) != TOKEN_COLON) {
|
||||
if (peek_tok_type(tokbuf) != TOKEN_COLON) {
|
||||
goto EXP;
|
||||
}
|
||||
node->label_stmt.label = parse_ident(parser);
|
||||
expecttok(parser, TOKEN_COLON);
|
||||
node->label_stmt.label = expect_pop_ident(tokbuf);
|
||||
expect_pop_tok(tokbuf, TOKEN_COLON);
|
||||
node->type = NT_STMT_LABEL;
|
||||
break;
|
||||
}
|
||||
case TOKEN_CASE: {
|
||||
// TODO label switch
|
||||
poptok(parser);
|
||||
pop_tok(tokbuf);
|
||||
error("unimplemented switch label");
|
||||
node->label_stmt.label = parse_expr(parser);
|
||||
// TODO 该表达式为const int
|
||||
expecttok(parser, TOKEN_COLON);
|
||||
expect_pop_tok(tokbuf, TOKEN_COLON);
|
||||
node->type = NT_STMT_CASE;
|
||||
break;
|
||||
}
|
||||
case TOKEN_DEFAULT: {
|
||||
// TODO label switch default
|
||||
poptok(parser);
|
||||
expecttok(parser, TOKEN_COLON);
|
||||
pop_tok(tokbuf);
|
||||
expect_pop_tok(tokbuf, TOKEN_COLON);
|
||||
node->type = NT_STMT_DEFAULT;
|
||||
break;
|
||||
}
|
||||
@ -226,15 +227,16 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
|
||||
*/
|
||||
EXP:
|
||||
node->expr_stmt.expr_stmt = parse_expr(parser);
|
||||
flushpeektok(parser);
|
||||
ttype = peektoktype(parser);
|
||||
flush_peek_tok(tokbuf);
|
||||
ttype = peek_tok_type(tokbuf);
|
||||
if (ttype != TOKEN_SEMICOLON) {
|
||||
error("exp must end with \";\"");
|
||||
}
|
||||
poptok(parser);
|
||||
pop_tok(tokbuf);
|
||||
node->type = NT_STMT_EXPR;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
@ -2,162 +2,30 @@
|
||||
#include "../type.h"
|
||||
#include "ast.h"
|
||||
|
||||
// /* 状态跳转表定义 */
|
||||
// typedef void (*StateHandler)(struct Parser*, struct ASTNode**);
|
||||
|
||||
// enum TypeParseState {
|
||||
// TPS_BASE_TYPE, // 解析基础类型 (int/char等)
|
||||
// TPS_QUALIFIER, // 解析限定符 (const/volatile)
|
||||
// TPS_POINTER, // 解析指针 (*)
|
||||
// TPS_ARRAY, // 解析数组维度 ([n])
|
||||
// TPS_FUNC_PARAMS, // 解析函数参数列表
|
||||
// TPS_END,
|
||||
// };
|
||||
|
||||
// ;
|
||||
|
||||
// /* 状态处理函数前置声明 */
|
||||
// static void handle_base_type(struct Parser*, struct ASTNode**);
|
||||
// static void handle_qualifier(struct Parser*, struct ASTNode**);
|
||||
// static void handle_pointer(struct Parser*, struct ASTNode**);
|
||||
// static void handle_array(struct Parser*, struct ASTNode**);
|
||||
// static void handle_func_params(struct Parser*, struct ASTNode**);
|
||||
// static void handle_error(struct Parser*, struct ASTNode**);
|
||||
|
||||
// /* 状态跳转表(核心优化部分) */
|
||||
// static const struct StateTransition {
|
||||
// enum TokenType tok; // 触发token
|
||||
// StateHandler handler; // 处理函数
|
||||
// enum TypeParseState next_state; // 下一个状态
|
||||
// } state_table[][8] = {
|
||||
// [TPS_QUALIFIER] = {
|
||||
// {TOKEN_CONST, handle_qualifier, TPS_QUALIFIER},
|
||||
// {TOKEN_VOLATILE, handle_qualifier, TPS_QUALIFIER},
|
||||
// {TOKEN_VOID, handle_base_type, TPS_POINTER},
|
||||
// {TOKEN_CHAR, handle_base_type, TPS_POINTER},
|
||||
// {TOKEN_INT, handle_base_type, TPS_POINTER},
|
||||
// {TOKEN_EOF, handle_error, TPS_QUALIFIER},
|
||||
// /* 其他token默认处理 */
|
||||
// {0, NULL, TPS_BASE_TYPE}
|
||||
// },
|
||||
// [TPS_BASE_TYPE] = {
|
||||
// {TOKEN_MUL, handle_pointer, TPS_POINTER},
|
||||
// {TOKEN_L_BRACKET, handle_array, TPS_ARRAY},
|
||||
// {TOKEN_L_PAREN, handle_func_params,TPS_FUNC_PARAMS},
|
||||
// {TOKEN_EOF, NULL, TPS_END},
|
||||
// {0, NULL, TPS_POINTER}
|
||||
// },
|
||||
// [TPS_POINTER] = {
|
||||
// {TOKEN_MUL, handle_pointer, TPS_POINTER},
|
||||
// {TOKEN_L_BRACKET, handle_array, TPS_ARRAY},
|
||||
// {TOKEN_L_PAREN, handle_func_params,TPS_FUNC_PARAMS},
|
||||
// {0, NULL, TPS_END}
|
||||
// },
|
||||
// [TPS_ARRAY] = {
|
||||
// {TOKEN_L_BRACKET, handle_array, TPS_ARRAY},
|
||||
// {TOKEN_L_PAREN, handle_func_params,TPS_FUNC_PARAMS},
|
||||
// {0, NULL, TPS_END}
|
||||
// },
|
||||
// [TPS_FUNC_PARAMS] = {
|
||||
// {0, NULL, TPS_END}
|
||||
// }
|
||||
// };
|
||||
|
||||
// /* 新的类型解析函数 */
|
||||
// struct ASTNode* parse_type(struct Parser* p) {
|
||||
// struct ASTNode* type_root = NULL;
|
||||
// struct ASTNode** current = &type_root;
|
||||
// enum TypeParseState state = TPS_QUALIFIER;
|
||||
|
||||
// while (state != TPS_END) {
|
||||
// enum TokenType t = peektoktype(p);
|
||||
// const struct StateTransition* trans = state_table[state];
|
||||
|
||||
// // 查找匹配的转换规则
|
||||
// while (trans->tok != 0 && trans->tok != t) {
|
||||
// trans++;
|
||||
// }
|
||||
|
||||
// if (trans->handler) {
|
||||
// trans->handler(p, current);
|
||||
// } else if (trans->tok == 0) { // 默认规则
|
||||
// state = trans->next_state;
|
||||
// continue;
|
||||
// } else {
|
||||
// error("syntax error type parse error");
|
||||
// }
|
||||
|
||||
// state = trans->next_state;
|
||||
// }
|
||||
|
||||
// return type_root;
|
||||
// }
|
||||
|
||||
// /* 具体状态处理函数实现 */
|
||||
// static void handle_qualifier(struct Parser* p, struct ASTNode** current) {
|
||||
// struct ASTNode* node = new_ast_node();
|
||||
// node->node_type = NT_TYPE_QUAL;
|
||||
// node->data.data_type = poptok(p).type;
|
||||
|
||||
// if (*current) {
|
||||
// (*current)->child.decl.type = node;
|
||||
// } else {
|
||||
// *current = node;
|
||||
// }
|
||||
// }
|
||||
|
||||
// static void handle_base_type(struct Parser* p, struct ASTNode** current) {
|
||||
// struct ASTNode* node = new_ast_node();
|
||||
// node->node_type = NT_TYPE_BASE;
|
||||
// node->data.data_type = poptok(p).type;
|
||||
|
||||
// // 链接到当前节点链的末端
|
||||
// while (*current && (*current)->child.decl.type) {
|
||||
// current = &(*current)->child.decl.type;
|
||||
// }
|
||||
|
||||
// if (*current) {
|
||||
// (*current)->child.decl.type = node;
|
||||
// } else {
|
||||
// *current = node;
|
||||
// }
|
||||
// }
|
||||
|
||||
// static void handle_pointer(struct Parser* p, struct ASTNode** current) {
|
||||
// poptok(p); // 吃掉*
|
||||
// struct ASTNode* node = new_ast_node();
|
||||
// node->node_type = NT_TYPE_PTR;
|
||||
|
||||
// // 插入到当前节点之前
|
||||
// node->child.decl.type = *current;
|
||||
// *current = node;
|
||||
// }
|
||||
|
||||
// /* 其他处理函数类似实现... */
|
||||
|
||||
struct ASTNode* parser_ident_without_pop(struct Parser* parser) {
|
||||
flushpeektok(parser);
|
||||
struct Token* tok = peektok(parser);
|
||||
ast_node_t* new_ast_ident_node(tok_t* tok) {
|
||||
if (tok->type != TOKEN_IDENT) {
|
||||
error("syntax error: want identifier but got %d", tok->type);
|
||||
}
|
||||
struct ASTNode* node = new_ast_node();
|
||||
ast_node_t* node = new_ast_node();
|
||||
node->type = NT_TERM_IDENT;
|
||||
node->syms.tok = *tok;
|
||||
node->syms.decl_node = NULL;
|
||||
return node;
|
||||
}
|
||||
|
||||
struct ASTNode* parse_ident(struct Parser* parser) {
|
||||
struct ASTNode* node = parser_ident_without_pop(parser);
|
||||
poptok(parser);
|
||||
ast_node_t* expect_pop_ident(tok_buf_t* tokbuf) {
|
||||
flush_peek_tok(tokbuf);
|
||||
tok_t* tok = peek_tok(tokbuf);
|
||||
ast_node_t* node = new_ast_ident_node(tok);
|
||||
pop_tok(tokbuf);
|
||||
return node;
|
||||
}
|
||||
|
||||
struct ASTNode* parse_type(struct Parser* parser) {
|
||||
flushpeektok(parser);
|
||||
enum TokenType ttype = peektoktype(parser);
|
||||
enum DataType dtype;
|
||||
ast_node_t* parse_type(parser_t* parser) {
|
||||
tok_buf_t* tokbuf = &parser->tokbuf;
|
||||
flush_peek_tok(tokbuf);
|
||||
tok_type_t ttype = peek_tok_type(tokbuf);
|
||||
data_type_t dtype;
|
||||
switch(ttype) {
|
||||
case TOKEN_VOID: dtype = TYPE_VOID; break;
|
||||
case TOKEN_CHAR: dtype = TYPE_CHAR; break;
|
||||
@ -170,13 +38,14 @@ struct ASTNode* parse_type(struct Parser* parser) {
|
||||
error("无效的类型说明符");
|
||||
}
|
||||
|
||||
struct ASTNode* node = new_ast_node();
|
||||
ast_node_t* node = new_ast_node();
|
||||
node->type = NT_TERM_TYPE;
|
||||
// node->data.data_type = dtype;
|
||||
poptok(parser);
|
||||
// TODO added by disable warning, will add typing system
|
||||
dtype += 1;
|
||||
pop_tok(tokbuf);
|
||||
|
||||
if (peektoktype(parser) == TOKEN_MUL) {
|
||||
poptok(parser);
|
||||
if (peek_tok_type(tokbuf) == TOKEN_MUL) {
|
||||
pop_tok(tokbuf);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
@ -1,136 +1,136 @@
|
||||
#include "../parser.h"
|
||||
#include "../type.h"
|
||||
// #include "../parser.h"
|
||||
// #include "../type.h"
|
||||
|
||||
enum TypeParseState {
|
||||
TPS_BASE_TYPE, // 解析基础类型 (int/char等)
|
||||
TPS_QUALIFIER, // 解析限定符 (const/volatile)
|
||||
TPS_POINTER, // 解析指针 (*)
|
||||
TPS_ARRAY, // 解析数组维度 ([n])
|
||||
TPS_FUNC_PARAMS // 解析函数参数列表
|
||||
};
|
||||
// enum TypeParseState {
|
||||
// TPS_BASE_TYPE, // 解析基础类型 (int/char等)
|
||||
// TPS_QUALIFIER, // 解析限定符 (const/volatile)
|
||||
// TPS_POINTER, // 解析指针 (*)
|
||||
// TPS_ARRAY, // 解析数组维度 ([n])
|
||||
// TPS_FUNC_PARAMS // 解析函数参数列表
|
||||
// };
|
||||
|
||||
struct ASTNode* parse_type(struct Parser* p) {
|
||||
struct ASTNode* type_root = new_ast_node();
|
||||
struct ASTNode* current = type_root;
|
||||
current->type = NT_TYPE_BASE;
|
||||
// ast_node_t* parse_type(parser_t* p) {
|
||||
// ast_node_t* type_root = new_ast_node();
|
||||
// ast_node_t* current = type_root;
|
||||
// current->type = NT_TYPE_BASE;
|
||||
|
||||
enum TypeParseState state = TPS_QUALIFIER;
|
||||
int pointer_level = 0;
|
||||
// enum TypeParseState state = TPS_QUALIFIER;
|
||||
// int pointer_level = 0;
|
||||
|
||||
while (1) {
|
||||
enum TokenType t = peektoktype(p);
|
||||
// while (1) {
|
||||
// tok_type_t t = peektoktype(p);
|
||||
|
||||
switch (state) {
|
||||
// 基础类型解析 (int, char等)
|
||||
case TPS_BASE_TYPE:
|
||||
if (is_base_type(t)) {
|
||||
// current->data.data_type = token_to_datatype(t);
|
||||
poptok(p);
|
||||
state = TPS_POINTER;
|
||||
} else {
|
||||
error("Expected type specifier");
|
||||
}
|
||||
break;
|
||||
// switch (state) {
|
||||
// // 基础类型解析 (int, char等)
|
||||
// case TPS_BASE_TYPE:
|
||||
// if (is_base_type(t)) {
|
||||
// // current->data.data_type = token_to_datatype(t);
|
||||
// pop_tok(p);
|
||||
// state = TPS_POINTER;
|
||||
// } else {
|
||||
// error("Expected type specifier");
|
||||
// }
|
||||
// break;
|
||||
|
||||
// 类型限定符 (const/volatile)
|
||||
case TPS_QUALIFIER:
|
||||
if (t == TOKEN_CONST || t == TOKEN_VOLATILE) {
|
||||
struct ASTNode* qual_node = new_ast_node();
|
||||
qual_node->type = NT_TYPE_QUAL;
|
||||
qual_node->data.data_type = t; // 复用data_type字段存储限定符
|
||||
current->child.decl.type = qual_node;
|
||||
current = qual_node;
|
||||
poptok(p);
|
||||
} else {
|
||||
state = TPS_BASE_TYPE;
|
||||
}
|
||||
break;
|
||||
// // 类型限定符 (const/volatile)
|
||||
// case TPS_QUALIFIER:
|
||||
// if (t == TOKEN_CONST || t == TOKEN_VOLATILE) {
|
||||
// ast_node_t* qual_node = new_ast_node();
|
||||
// qual_node->type = NT_TYPE_QUAL;
|
||||
// qual_node->data.data_type = t; // 复用data_type字段存储限定符
|
||||
// current->child.decl.type = qual_node;
|
||||
// current = qual_node;
|
||||
// pop_tok(p);
|
||||
// } else {
|
||||
// state = TPS_BASE_TYPE;
|
||||
// }
|
||||
// break;
|
||||
|
||||
// 指针解析 (*)
|
||||
case TPS_POINTER:
|
||||
if (t == TOKEN_MUL) {
|
||||
struct ASTNode* ptr_node = new_ast_node();
|
||||
ptr_node->type = NT_TYPE_PTR;
|
||||
current->child.decl.type = ptr_node;
|
||||
current = ptr_node;
|
||||
pointer_level++;
|
||||
poptok(p);
|
||||
} else {
|
||||
state = TPS_ARRAY;
|
||||
}
|
||||
break;
|
||||
// // 指针解析 (*)
|
||||
// case TPS_POINTER:
|
||||
// if (t == TOKEN_MUL) {
|
||||
// ast_node_t* ptr_node = new_ast_node();
|
||||
// ptr_node->type = NT_TYPE_PTR;
|
||||
// current->child.decl.type = ptr_node;
|
||||
// current = ptr_node;
|
||||
// pointer_level++;
|
||||
// pop_tok(p);
|
||||
// } else {
|
||||
// state = TPS_ARRAY;
|
||||
// }
|
||||
// break;
|
||||
|
||||
// 数组维度 ([n])
|
||||
case TPS_ARRAY:
|
||||
if (t == TOKEN_L_BRACKET) {
|
||||
poptok(p); // 吃掉[
|
||||
struct ASTNode* arr_node = new_ast_node();
|
||||
arr_node->type = NT_TYPE_ARRAY;
|
||||
// // 数组维度 ([n])
|
||||
// case TPS_ARRAY:
|
||||
// if (t == TOKEN_L_BRACKET) {
|
||||
// pop_tok(p); // 吃掉[
|
||||
// ast_node_t* arr_node = new_ast_node();
|
||||
// arr_node->type = NT_TYPE_ARRAY;
|
||||
|
||||
// 解析数组大小(仅语法检查)
|
||||
if (peektoktype(p) != TOKEN_R_BRACKET) {
|
||||
parse_expr(p); // 不计算实际值
|
||||
}
|
||||
// // 解析数组大小(仅语法检查)
|
||||
// if (peektoktype(p) != TOKEN_R_BRACKET) {
|
||||
// parse_expr(p); // 不计算实际值
|
||||
// }
|
||||
|
||||
expecttok(p, TOKEN_R_BRACKET);
|
||||
current->child.decl.type = arr_node;
|
||||
current = arr_node;
|
||||
} else {
|
||||
state = TPS_FUNC_PARAMS;
|
||||
}
|
||||
break;
|
||||
// expecttok(p, TOKEN_R_BRACKET);
|
||||
// current->child.decl.type = arr_node;
|
||||
// current = arr_node;
|
||||
// } else {
|
||||
// state = TPS_FUNC_PARAMS;
|
||||
// }
|
||||
// break;
|
||||
|
||||
// 函数参数列表
|
||||
case TPS_FUNC_PARAMS:
|
||||
if (t == TOKEN_L_PAREN) {
|
||||
struct ASTNode* func_node = new_ast_node();
|
||||
func_node->type = NT_TYPE_FUNC;
|
||||
current->child.decl.type = func_node;
|
||||
// // 函数参数列表
|
||||
// case TPS_FUNC_PARAMS:
|
||||
// if (t == TOKEN_L_PAREN) {
|
||||
// ast_node_t* func_node = new_ast_node();
|
||||
// func_node->type = NT_TYPE_FUNC;
|
||||
// current->child.decl.type = func_node;
|
||||
|
||||
// 解析参数列表(仅结构,不验证类型)
|
||||
parse_param_list(p, func_node);
|
||||
current = func_node;
|
||||
} else {
|
||||
return type_root; // 类型解析结束
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否是基础类型
|
||||
static int is_base_type(enum TokenType t) {
|
||||
return t >= TOKEN_VOID && t <= TOKEN_DOUBLE;
|
||||
}
|
||||
|
||||
// // 转换token到数据类型(简化版)
|
||||
// static enum DataType token_to_datatype(enum TokenType t) {
|
||||
// static enum DataType map[] = {
|
||||
// [TOKEN_VOID] = DT_VOID,
|
||||
// [TOKEN_CHAR] = DT_CHAR,
|
||||
// [TOKEN_INT] = DT_INT,
|
||||
// // ...其他类型映射
|
||||
// };
|
||||
// return map[t];
|
||||
// // 解析参数列表(仅结构,不验证类型)
|
||||
// parse_param_list(p, func_node);
|
||||
// current = func_node;
|
||||
// } else {
|
||||
// return type_root; // 类型解析结束
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// 解析参数列表(轻量级)
|
||||
static void parse_param_list(struct Parser* p, struct ASTNode* func) {
|
||||
expecttok(p, TOKEN_L_PAREN);
|
||||
|
||||
while (peektoktype(p) != TOKEN_R_PAREN) {
|
||||
struct ASTNode* param = parse_type(p); // 递归解析类型
|
||||
|
||||
// 允许可选参数名(仅语法检查)
|
||||
if (peektoktype(p) == TOKEN_IDENT) {
|
||||
poptok(p); // 吃掉参数名
|
||||
}
|
||||
|
||||
if (peektoktype(p) == TOKEN_COMMA) {
|
||||
poptok(p);
|
||||
}
|
||||
}
|
||||
|
||||
expecttok(p, TOKEN_R_PAREN);
|
||||
}
|
||||
// // 判断是否是基础类型
|
||||
// static int is_base_type(tok_type_t t) {
|
||||
// return t >= TOKEN_VOID && t <= TOKEN_DOUBLE;
|
||||
// }
|
||||
|
||||
// // // 转换token到数据类型(简化版)
|
||||
// // static enum DataType token_to_datatype(tok_type_t t) {
|
||||
// // static enum DataType map[] = {
|
||||
// // [TOKEN_VOID] = DT_VOID,
|
||||
// // [TOKEN_CHAR] = DT_CHAR,
|
||||
// // [TOKEN_INT] = DT_INT,
|
||||
// // // ...其他类型映射
|
||||
// // };
|
||||
// // return map[t];
|
||||
// // }
|
||||
|
||||
// // 解析参数列表(轻量级)
|
||||
// static void parse_param_list(parser_t* p, ast_node_t* func) {
|
||||
// expecttok(p, TOKEN_L_PAREN);
|
||||
|
||||
// while (peektoktype(p) != TOKEN_R_PAREN) {
|
||||
// ast_node_t* param = parse_type(p); // 递归解析类型
|
||||
|
||||
// // 允许可选参数名(仅语法检查)
|
||||
// if (peektoktype(p) == TOKEN_IDENT) {
|
||||
// pop_tok(p); // 吃掉参数名
|
||||
// }
|
||||
|
||||
// if (peektoktype(p) == TOKEN_COMMA) {
|
||||
// pop_tok(p);
|
||||
// }
|
||||
// }
|
||||
|
||||
// expecttok(p, TOKEN_R_PAREN);
|
||||
// }
|
||||
|
||||
|
Reference in New Issue
Block a user