├── CRB.h ├── CRB_dev.h ├── DBG.h ├── MEM.h ├── Makefile ├── README.md ├── create.c ├── crowbar.h ├── crowbar.l ├── crowbar.y ├── debug ├── Makefile ├── debug.c └── debug.h ├── eval.c ├── lex.yy.c ├── memory ├── Makefile ├── main.c ├── memory.c ├── memory.h ├── memory_test.c ├── minunit.h ├── storage.c └── testp ├── string.c ├── util.c ├── y.output ├── y.tab.c └── y.tab.h /CRB.h: -------------------------------------------------------------------------------- 1 | #ifndef PUBLIC_CRB_H_INCLUDED 2 | #define PUBLIC_CRB_H_INCLUDED 3 | #include 4 | 5 | typedef struct CRB_Interpreter_tag CRB_Interpreter; 6 | CRB_Interpreter *CRB_create_interpreter(void); 7 | void CRB_compile(CRB_Interpreter *interpreter, FILE *fp); 8 | void CRB_interpret(CRB_Interpreter *interpreter); 9 | void CRB_dispose_interpreter(CRB_Interpreter *interpreter); 10 | 11 | #endif /* PUBLIC_CRB_H_INCLUDED */ 12 | -------------------------------------------------------------------------------- /CRB_dev.h: -------------------------------------------------------------------------------- 1 | #ifndef PUBLIC_CRB_DEV_H_INCLUDED 2 | #define PUBLIC_CRB_DEV_H_INCLUDED 3 | 4 | /** 5 | * Crowbar 里面的布尔类型 6 | */ 7 | typedef enum { 8 | CRB_FALSE = 0, 9 | CRB_TRUE = 1 10 | } CRB_Boolean; 11 | 12 | /** 13 | * CRB 里面的字符串类型 14 | */ 15 | typedef struct CRB_String_tag CRB_String; 16 | 17 | typedef struct { 18 | char *name; 19 | } CRB_NativePointerInfo; 20 | 21 | /** 22 | * Crowbar 里面支持的所有的值类型 23 | */ 24 | typedef enum { 25 | CRB_BOOLEAN_VALUE = 1, 26 | CRB_INT_VALUE, 27 | CRB_DOUBLE_VALUE, 28 | CRB_STRING_VALUE, 29 | CRB_NATIVE_POINTER_VALUE, 30 | CRB_NULL_VALUE 31 | } CRB_ValueType; 32 | 33 | typedef struct { 34 | CRB_NativePointerInfo *info; 35 | void *pointer; 36 | } CRB_NativePointer; 37 | 38 | typedef struct { 39 | CRB_ValueType type; 40 | union { 41 | CRB_Boolean boolean_value; 42 | int int_value; 43 | double double_value; 44 | CRB_String *string_value; 45 | CRB_NativePointer native_pointer; 46 | }u; 47 | } CRB_Value; 48 | 49 | typedef CRB_Value CRB_NativeFunctionProc(CRB_Interpreter *interpreter, 50 | int arg_count, 51 | CRB_Value *args); 52 | 53 | void CRB_add_native_function(CRB_Interpreter *interpreter, 54 | char *name, 55 | CRB_NativeFunctionProc *proc); 56 | 57 | void CRB_add_global_variable(CRB_Interpreter *interpreter, 58 | char *identifier, 59 | CRB_Value *value); 60 | 61 | #endif /* PUBLIC_CRB_DEV_H_INCLUDED */ 62 | -------------------------------------------------------------------------------- /DBG.h: -------------------------------------------------------------------------------- 1 | #ifndef PUBLIC_DBG_H_INCLUDED 2 | #define PUBLIC_DBG_H_INCLUDED 3 | #include 4 | #include /* 引入这个干嘛? */ 5 | 6 | /** 7 | * 这里 DBG_Controller_tag 是个不完整类型,因为这里只定义了一个名字 8 | * 没有定义它具体的结构,因此是一个 「不完全类型」,只能使用这个类型 9 | * 的指针,不能使用它的实例,也没办法对它的类型使用 sizeof 10 | */ 11 | typedef struct DBG_Controller_tag * DBG_Controller; 12 | void DBG_set(DBG_Controller, char *file, int line); 13 | void DBG_set_expression(char *expression); 14 | 15 | #ifdef DBG_NO_DEBUG 16 | #define DBG_create_controller() ((void)0) 17 | #define DBG_set_debug_level(level) ((void)0) 18 | #define DBG_set_debug_write_fp(fp) ((void)0) 19 | #define DBG_assert(expression, arg) ((void)0) 20 | #define DBG_panic(arg) ((void)0) 21 | #define DBG_debug_write(arg) ((void)0) 22 | #else /* DBG_NO_DEBUG */ 23 | #ifdef DBG_CONTROLLER 24 | #define DBG_CURRENT_CONTROLLER DBG_CONTROLLER 25 | #else /* DBG_CONTROLLER */ 26 | #define DBG_CURRENT_CONTROLLER dbg_default_controller 27 | #endif /* DBG_CONTROLLER */ 28 | extern DBG_Controller DBG_CURRENT_CONTROLLER; 29 | 30 | #define DBG_create_controller (DBG_create_controller_func()) 31 | #define DBG_set_debug_level(level) \ 32 | (DBG_set_debug_level_func(DBG_CURRENT_CONTROLLER, (level))) 33 | #define DBG_set_debug_write_fp(fp) \ 34 | (DBG_set_debug_write_fp(DBG_CURRENT_CONTROLLER, (fp))) 35 | #define DBG_assert(expression, arg) \ 36 | ((expression)? (void)0 : \ 37 | ((DBG_set(DBG_CURRENT_CONTROLLER, __FILE__, __LINE__)),\ 38 | (DBG_set_expression(#expression)),\ 39 | DBG_assert_func arg)) 40 | #define DBG_panic(arg)\ 41 | ((DBG_set(DBG_CURRENT_CONTROLLER, __FILE__, __LINE__)),\ 42 | DBG_debug_write_func arg) 43 | #endif /* DBG_NO_DEBUG */ 44 | 45 | typedef enum { 46 | DBG_TRUE = 1, 47 | DBG_FALSE = 0 48 | } DBG_Boolean; 49 | 50 | 51 | DBG_Controller DBG_create_controller_func(void); 52 | void DBG_set_debug_level_func(DBG_Controller controller, int level); 53 | void DBG_set_debug_write_fp_func(DBG_Controller controller, FILE *fp); 54 | void DBG_assert_func(char *fmt, ...); 55 | void DBG_panic_func(char *fmt, ...); 56 | void DBG_debug_write_func(int level, char *fmt, ...); 57 | #endif /* PUBLIC_DBG_H_INCLUDED */ 58 | 59 | -------------------------------------------------------------------------------- /MEM.h: -------------------------------------------------------------------------------- 1 | #ifndef PUBLIC_MEM_H 2 | #define PUBLIC_MEM_H 3 | 4 | /** 5 | * 内存出错之后的处理方式 6 | */ 7 | typedef enum { 8 | MEM_FAIL_AND_EXIT, 9 | MEM_FAIL_AND_RETURN 10 | } MEM_FailMode; 11 | 12 | typedef struct MEM_Controller_tag *MEM_Controller; 13 | typedef struct MEM_Storage_tag *MEM_Storage; 14 | extern MEM_Controller mem_default_controller; 15 | 16 | #ifdef MEM_CONTROLLER 17 | #define MEM_CURRENT_CONTROLLER MEM_CONTROLLER 18 | #else /* MEM_CONTROLLER */ 19 | #define MEM_CURRENT_CONTROLLER mem_default_controller 20 | #endif /* MEM_CONTROLLER */ 21 | 22 | /** 23 | * 内存出错处理器 24 | */ 25 | typedef void (*MEM_ErrorHandler)(MEM_Controller, char *, int, char *); 26 | 27 | /** 28 | * 分配内存的函数 29 | */ 30 | void *MEM_malloc_func(MEM_Controller controller, 31 | char *filename, int line, size_t size); 32 | /** 33 | * 对已经分配的一段内存已经扩充 34 | */ 35 | void *MEM_realloc_func(MEM_Controller controller, 36 | char *filename, int line, void *ptr, size_t size); 37 | /** 38 | * 把当前所有的内存详情都 dump 出来的函数 39 | */ 40 | void MEM_dump_blocks_func(MEM_Controller controller, FILE *fp); 41 | 42 | /** 43 | * 创建一个新的内存 storage 44 | */ 45 | MEM_Storage MEM_open_storage_func(MEM_Controller controller, char* filename, int line, int page_size); 46 | 47 | /** 48 | * 从 storage 里面分配一块内存出来 49 | */ 50 | void* MEM_storage_malloc_func(MEM_Controller controller, 51 | char* filename, 52 | int line, 53 | MEM_Storage storage, 54 | size_t size); 55 | /** 56 | * 销毁一个内存 storage 57 | */ 58 | void MEM_dispose_storage_func(MEM_Controller controller, MEM_Storage storage); 59 | 60 | /* 定义外部更简单的调用方法 */ 61 | #define MEM_malloc(size)\ 62 | (MEM_malloc_func(MEM_CURRENT_CONTROLLER,\ 63 | __FILE__, __LINE__, size)) 64 | #define MEM_realloc(size)\ 65 | (MEM_realloc_func(MEM_CURRENT_CONTROLLER, __FILE__, __LINE__, ptr, size)) 66 | 67 | #define MEM_dump_blocks(fp)\ 68 | (MEM_dump_blocks_func(MEM_CURRENT_CONTROLLER, fp)) 69 | 70 | #define MEM_open_storage(page_size)\ 71 | (MEM_open_storage_func(MEM_CURRENT_CONTROLLER,\ 72 | __FILE__, __LINE__, page_size)) 73 | 74 | #define MEM_storage_malloc(storage, size)\ 75 | (MEM_storage_malloc_func(MEM_CURRENT_CONTROLLER, storage,\ 76 | __FILE__, __LINE__, size)) 77 | 78 | #define MEM_dispose_storage(storage)\ 79 | (MEM_dispose_storage_func(MEM_CURRENT_CONTROLLER, storage)) 80 | #endif 81 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TARGET = crowbar 2 | CC = gcc 3 | OBJS = \ 4 | lex.yy.o\ 5 | y.tab.o 6 | 7 | CFLAGS = -c -g -Wall -Wswitch-enum -ansi -DDEBUG 8 | INCLUDES = \ 9 | 10 | $(TARGET):$(OBJS) 11 | cd ./memory; $(MAKE); 12 | cd ./debug; $(MAKE); 13 | $(CC) $(OBJS) -o $@ -lm 14 | 15 | clean: 16 | rm -rf *.o lex.yy.c y.tab.c y.tab.h *~ 17 | 18 | y.tab.h: 19 | bison --yacc -dv crowbar.y 20 | y.tab.c: crowbar.y 21 | bison --yacc -dv crowbar.y 22 | lex.yy.c: crowbar.l crowbar.y y.tab.h 23 | flex crowbar.l 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # crowbar 2 | 3 | 加了注释的、[《自制编程语言》](http://www.duokan.com/book/73839) 一书的、crowbar 语言的源代码。 4 | -------------------------------------------------------------------------------- /create.c: -------------------------------------------------------------------------------- 1 | #include "MEM.h" 2 | #include "DBG.h" 3 | #include "crowbar.h" 4 | 5 | void 6 | crb_function_define(char *identifier, ParameterList *parameter_list, 7 | Block *block) 8 | { 9 | FunctionDefinition *f; 10 | CRB_Interpreter *iter; 11 | 12 | if (crb_search_function(identifier)) { 13 | crb_compile_error(FUNCTION_MULTIPLE_DEFINE_ERR, 14 | STRING_MESSAGE_ARGUMENT, "name", identifier, 15 | MESSAGE_ARGUMENT_END); 16 | return; 17 | } 18 | 19 | inter = crb_get_current_interpreter(); 20 | 21 | f = crb_malloc(sizeof(FunctionDefinition)); 22 | f->name = identifier; 23 | f->type = CROWBAR_FUNCTION_DEFINITION; 24 | f->u.crowbar_f.parameter = parameter_list; 25 | f->u.crowbar_f.block = block; 26 | f->next = inter->function_list; 27 | inter->function_list = f; 28 | } 29 | 30 | StatementList * 31 | crb_create_statement_list(Statement *statement) 32 | { 33 | StatementList *sl; 34 | sl = crb_malloc(sizeof(StatementList)); 35 | sl->statement = statement; 36 | sl->next = NULL; 37 | 38 | return sl; 39 | } 40 | 41 | StatementList * 42 | crb_chain_statement_list(StatementList *list, Statement *statement) 43 | { 44 | StatementList *pos; 45 | 46 | if (list == NULL) { 47 | return crb_create_statement_list(statement); 48 | } 49 | 50 | for (pos = list; pos->next; pos = pos->next) 51 | ; 52 | 53 | pos->next = crb_create_statement_list(statement); 54 | } 55 | 56 | Expression * 57 | crb_alloc_expression(ExpressionType type) 58 | { 59 | Expression *exp; 60 | exp = crb_alloc(sizeof(Expression)); 61 | exp->type = type; 62 | exp->line_number = crb_get_current_interpreter()->current_line_number; 63 | 64 | return exp; 65 | } 66 | 67 | ArgumentList * 68 | crb_create_argument_list(Expression *expression) 69 | { 70 | ArgumentList *al; 71 | al = crb_malloc(sizeof(ArgumentList)); 72 | al->expression = expression; 73 | al->next = NULL; 74 | 75 | return al; 76 | } 77 | 78 | ArgumentList * 79 | crb_chain_argument_list(ArgumentList * list, Expression *expression) 80 | { 81 | ArgumentList *pos; 82 | for (pos = list; pos; pos = pos->next) 83 | ; 84 | 85 | pos->next = crb_create_argument_list(expression); 86 | 87 | return list; 88 | } 89 | 90 | Expression * 91 | crb_create_assign_expression(char *variable, Expression *operand) 92 | { 93 | Expression *exp; 94 | exp = crb_alloc_expression(ASSIGN_EXPRESSION); 95 | exp->u.assign_expression.variable = variable; 96 | exp->u.assign_expression.operand = operand; 97 | 98 | return exp; 99 | } 100 | 101 | /** 102 | * 把常量(int, double, boolean) 根据类型包装成对应的表达式。 103 | */ 104 | static Expression 105 | convert_value_to_expression(CRB_Value *v) 106 | { 107 | Expression expr; 108 | 109 | if (v->type == CRB_INT_VALUE) { 110 | expr.type = INT_EXPRESSION; 111 | expr.u.int_value = v.u.int_value; 112 | } else if (v-> type == CRB_DOUBLE_VALUE) { 113 | expr.type = DOUBLE_EXPRESSION; 114 | expr.u.double_value = v.u.double_value; 115 | } else { 116 | DBG_assert(v-> type == CRB_BOOLEAN_VALUE, 117 | ("v->type..%d\n", v->type)); 118 | expr.type = BOOLEAN_EXPRESSION; 119 | expr.u.boolean_value = v->u.boolean_value; 120 | } 121 | 122 | return expr; 123 | } 124 | 125 | Expression * 126 | crb_create_binary_expression(ExpressionType operator, 127 | Expression *left, Expression *right) 128 | { 129 | // 如果左右两边都是数字,那么做常量折叠 130 | if ((left->type == INT_EXPRESSION 131 | || left->type == DOUBLE_EXPRESSION) 132 | && (right->type == INT_EXPRESSION 133 | || right->type = DOUBLE_EXPRESSION)) { 134 | CRB_Value v; 135 | v = crb_eval_binary_expression(crb_get_current_interpreter(), NULL, operator, left, right); 136 | *left = convert_value_to_expression(&v); 137 | 138 | return left; 139 | } else { 140 | Expression *exp; 141 | exp = crb_alloc_expression(operator); 142 | exp->u.binary_expression.left = left; 143 | exp->u.binary_expression.right = right; 144 | 145 | return exp; 146 | } 147 | } 148 | 149 | -------------------------------------------------------------------------------- /crowbar.h: -------------------------------------------------------------------------------- 1 | #ifndef PRIVATE_CROWBAR_H_INCLUDED 2 | #define PRIVATE_CROWBAR_H_INCLUDED 3 | #include 4 | #include "MEM.h" 5 | #include "CRB.h" 6 | #include "CRB_dev.h" 7 | 8 | #define LINE_BUF_SIZE (1024) 9 | 10 | /** 11 | * 编译错误 12 | */ 13 | typedef enum { 14 | /* 解析出错 */ 15 | PARSE_ERR = 1, 16 | /* 错误的字符 */ 17 | CHARACTER_INVALID_ERR, 18 | /* 一个函数定义了多次错误 */ 19 | FUNCTION_MULTIPLE_DEFINE_ERR, 20 | COMPILE_ERROR_COUNT_PLUS_1 21 | } CompileError; 22 | 23 | /** 24 | * 消息的参数类型 25 | */ 26 | typedef enum { 27 | INT_MESSAGE_ARGUMENT = 1, 28 | DOUBLE_MESSAGE_ARGUMENT, 29 | STRING_MESSAGE_ARGUMENT, 30 | CHARACTER_MESSAGE_ARGUMENT, 31 | POINTER_MESSAGE_ARGUMENT, 32 | MESSAGE_ARGUMENT_END 33 | } MessageArgumentType; 34 | 35 | typedef struct Variable_tag 36 | { 37 | /* 变量的名字 */ 38 | char *name; 39 | /* 变量的值 */ 40 | CRB_Value value; 41 | /* 下一个变量,组成一个链表 */ 42 | struct Variable_tag *next; 43 | } Variable; 44 | 45 | typedef enum { 46 | /* crowbar 里面的函数 */ 47 | CROWBAR_FUNCTION_DEFINITION = 1, 48 | /* native 函数 -- 其实就是 C 函数 */ 49 | NATIVE_FUNCTION_DEFINITION 50 | } FunctionDefinitionType; 51 | 52 | /** 53 | * 参数列表 54 | */ 55 | typedef struct ParameterList_tag { 56 | /* 参数的名字 */ 57 | char *name; 58 | /* 下一个参数 */ 59 | struct ParameterList_tag *next; 60 | } ParameterList; 61 | 62 | typedef struct Statement_tag Statement; 63 | 64 | typedef struct FunctionDefinition_tag { 65 | /* 函数的名字 */ 66 | char *name; 67 | /* 函数的类型 */ 68 | FunctionDefinitionType type; 69 | union { 70 | /* crowbar 函数体 */ 71 | struct { 72 | /* 参数列表 */ 73 | ParameterList *parameter; 74 | /* 函数体 */ 75 | Block *block; 76 | } crowbar_f; 77 | struct { 78 | CRB_NativeFunctionProc *proc; 79 | } native_f; 80 | } u; 81 | /* 下一个函数定义 */ 82 | struct FunctionDefinition_tag *next; 83 | } FunctionDefinition; 84 | 85 | struct CRB_Interpreter_tag { 86 | /* 编译使用用的内存 */ 87 | MEM_Storage interpreter_storage; 88 | /* 执行时候用的内存 */ 89 | MEM_Storage execute_storage; 90 | /* 全局变量列表 */ 91 | Variable *variable; 92 | /* 函数列表 */ 93 | FunctionDefinition *function_list; 94 | /* 顶层语句列表 */ 95 | StatementList *statement_list; 96 | /* 当前行号 */ 97 | int current_line_number; 98 | }; 99 | 100 | typedef struct Expression_tag Expression; 101 | typedef enum { 102 | BOOLEAN_EXPRESSION = 1, 103 | INT_EXPRESSION, 104 | DOUBLE_EXPRESSION, 105 | STRING_EXPRESSION, 106 | IDENTIFIER_EXPRESSION, 107 | ASSIGN_EXPRESSION, 108 | ADD_EXPRESSION, 109 | SUB_EXPRESSION, 110 | MUL_EXPRESSION, 111 | DIV_EXPRESSION, 112 | MOD_EXPRESSION, 113 | EQ_EXPRESSION, 114 | NE_EXPRESSION, 115 | GT_EXPRESSION, 116 | GE_EXPRESSION, 117 | LT_EXPRESSION, 118 | LE_EXPRESSION, 119 | LOGICAL_AND_EXPRESSION, 120 | LOGICAL_OR_EXPRESSION, 121 | MINUS_EXPRESSION, 122 | FUNCTION_CALL_EXPRESSION, 123 | NULL_EXPRESSION, 124 | EXPRESSION_TYPE_COUNT_PLUS_1 125 | } ExpressionType; 126 | 127 | typedef struct ArgumentList_tag { 128 | Expression *expression; 129 | struct ArgumentList_tag *next; 130 | } ArgumentList; 131 | 132 | typedef struct { 133 | char *variable; 134 | Expression *operand; 135 | } AssignExpression; 136 | 137 | typedef struct { 138 | Expression *left; 139 | Expression *right; 140 | } BinaryExpression; 141 | 142 | typedef struct { 143 | char *identifier; 144 | ArgumentList *argument; 145 | } FunctionCallExpression; 146 | 147 | struct Expression_tag { 148 | ExpressionType type; 149 | int line_number; 150 | union { 151 | CRB_Boolean boolean_value; 152 | int int_value; 153 | double double_value; 154 | char *string_value; 155 | char *identifier; 156 | AssignExpression assign_expression; 157 | BinaryExpression binary_expression; 158 | Expression *minus_expression; 159 | FunctionCallExpression function_call_expression; 160 | } u; 161 | }; 162 | 163 | typedef struct StatementList_tag { 164 | Statement *statement; 165 | struct StatementList_tag *next; 166 | } StatementList; 167 | 168 | typedef struct { 169 | StatementList *statemen_list; 170 | } Block; 171 | 172 | typedef struct IdentifierList_tag { 173 | char *name; 174 | struct IdentifierList_tag *next; 175 | } IdentifierList; 176 | 177 | typedef struct { 178 | IdentifierList *identifier_list; 179 | } GlobalStatement; 180 | 181 | typedef struct Elsif_tag { 182 | Expression *condition; 183 | Block *block; 184 | struct Elsif_tag *next; 185 | } Elsif; 186 | 187 | typedef struct { 188 | Expression *condition; 189 | Block *then_block; 190 | Elsif *elsif_list; 191 | Block *else_block; 192 | } IfStatement; 193 | 194 | typedef struct { 195 | Expression *condition; 196 | Block *block; 197 | } WhileStatement; 198 | 199 | typedef struct { 200 | Expression *init; 201 | Expression *condition; 202 | Expression *post; 203 | Block *block; 204 | } ForStatement; 205 | 206 | typedef struct { 207 | Expression *return_value; 208 | } ReturnStatement; 209 | 210 | typedef enum { 211 | EXPRESSION_STATEMENT = 1, 212 | GLOBAL_STATEMENT, 213 | IF_STATEMENT, 214 | WHILE_STATEMENT, 215 | FOR_STATEMENT, 216 | RETURN_STATEMENT, 217 | BREAK_STATEMENT, 218 | CONTINUE_STATEMENT, 219 | STATEMENT_TYPE_COUNT_PLUS_1 220 | } StatementType; 221 | 222 | struct Statement_tag { 223 | StatementType type; 224 | int line_number; 225 | union { 226 | Expression *expression_s; 227 | GlobalStatement global_s; 228 | IfStatement if_s; 229 | WhileStatement while_s; 230 | ForStatement for_s; 231 | ReturnStatement return_s; 232 | } u; 233 | }; 234 | 235 | typedef struct ParameterList_tag { 236 | char *name; 237 | struct ParameterList_tag *next; 238 | } ParameterList; 239 | 240 | typedef enum { 241 | CROWBAR_FUNCTION_DEFINITION = 1, 242 | NATIVE_FUNCTION_DEFINITION 243 | } FunctionDefinitionType; 244 | 245 | typedef struct FunctionDefinition_tag { 246 | char *name; 247 | FunctionDefinitionType type; 248 | union { 249 | struct { 250 | ParameterList *parameter; 251 | Block *block; 252 | } crowbar_f; 253 | struct { 254 | CRB_NativeFunctionProc *proc; 255 | } native_f; 256 | } u; 257 | 258 | struct FunctionDefinition_tag *next; 259 | } FunctionDefinition; 260 | 261 | 262 | typedef struct Variable_tag { 263 | char *name; 264 | CRB_Value value; 265 | struct Variable_tag *next; 266 | } Variable; 267 | 268 | typedef enum { 269 | NORMAL_STATEMENT_RESULT = 1, 270 | RETURN_STATEMENT_RESULT, 271 | BREAK_STATEMENT_RESULT, 272 | CONTINUE_STATEMENT_RESULT, 273 | STATEMENT_RESULT_TYPE_COUNT_PLUS_1 274 | } StatementResultType; 275 | 276 | typedef struct { 277 | StatementResultType type; 278 | union { 279 | CRB_Value return_value; 280 | } u; 281 | } StatementResult; 282 | 283 | typedef struct GlobalVariableRef_tag { 284 | Variable *variable; 285 | struct GlobalVariableRef_tag *next; 286 | } GlobalVariableRef; 287 | 288 | typedef struct { 289 | Variable *variable; 290 | GlobalVariableRef *next; 291 | } LocalEnvironment; 292 | 293 | struct CRB_String_tag { 294 | int ref_count; 295 | char *string; 296 | CRB_Boolean is_literal; 297 | }; 298 | 299 | typedef struct { 300 | CRB_String *strings; 301 | } StringPool; 302 | 303 | /* create.c */ 304 | void crb_function_define(char *identifier, ParameterList *parameter_list, 305 | Block *block); 306 | 307 | ParameterList *crb_create_parameter(char *identifier); 308 | 309 | ParameterList *crb_chain_parameter(ParameterList *list, 310 | char *identifier); 311 | 312 | ArgumentList *crb_create_argument_list(Expression *expression); 313 | 314 | ArgumentList *crb_chain_argument_list(ArgumentList *list, Expression *expr); 315 | 316 | StatementList *crb_create_statement_list(Statement *statement); 317 | StatementList *crb_chain_statement_list(StatementList *list, 318 | Statement *statement); 319 | Expression *crb_create_assign_expression(char *variable, 320 | Expression *operand); 321 | Expression *crb_create_binary_expression(ExpressionType operator, 322 | Expression *left, 323 | Expression *right); 324 | 325 | /* eval.c */ 326 | CRB_Value crb_eval_binary_expression(CRB_Interpreter *inter, 327 | LocalEnvironment *env, 328 | ExpressionType operator, 329 | Expression *left, 330 | Expression *right); 331 | /* string.c */ 332 | void crb_open_string_literal(void); 333 | 334 | /* error.c */ 335 | void crb_compile_error(CompileError id, ...); 336 | #endif /* PRIVATE_CROWBAR_H_INCLUDED */ 337 | 338 | -------------------------------------------------------------------------------- /crowbar.l: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include 4 | #include "DBG.h" 5 | #include "crowbar.h" 6 | #include "y.tab.h" 7 | 8 | int 9 | yywrap(void) 10 | { 11 | return 1; 12 | } 13 | 14 | static void 15 | increment_line_number(void) 16 | { 17 | crb_get_current_interpreter()->current_line_number++; 18 | } 19 | %} 20 | 21 | %start COMMENT STRING_LITERAL_STATE 22 | %% 23 | "function" return FUNCTION; 24 | "if" return IF; 25 | "else" return ELSE; 26 | "elsif" return ELSIF; 27 | "while" return WHILE; 28 | "for" return FOR; 29 | "return" return RETURN_T; 30 | "break" return BREAK; 31 | "continue" return CONTINUE; 32 | "null" return NULL_T; 33 | "true" return TRUE_T; 34 | "false" return FALSE_T; 35 | "global" return GLOBAL_T; 36 | "(" return LP; 37 | ")" return RP; 38 | "{" return LC; 39 | "}" return RC; 40 | ";" return SEMICOLON; 41 | "," return COMMA; 42 | "&&" return LOGICAL_AND; 43 | "||" return LOGICAL_OR; 44 | "=" return ASSIGN; 45 | "==" return EQ; 46 | "!=" return NE; 47 | ">" return GT; 48 | ">=" return GE; 49 | "<" return LT; 50 | "<=" return LE; 51 | "+" return ADD; 52 | "-" return SUB; 53 | "*" return MUL; 54 | "/" return DIV; 55 | "%" return MOD; 56 | [A-Za-z_][A-Za-z_0-9]* { 57 | yylval.identifier = crb_create_identifier(yytext); 58 | return IDENTIFIER; 59 | } 60 | ([1-9][0-9]*)|"0" { 61 | Expression *expression = crb_alloc_expression(INT_EXPRESSION); 62 | sscanf(yytext, "%d", &expression->u.int_value); 63 | yylval.expression = expression; 64 | return INT_LITERAL; 65 | } 66 | [0-9]+\.[0-9]+ { 67 | Expression *Expression = crb_alloc_expression(DOUBLE_EXPRESSION); 68 | sscanf(yytext, "%lf", &expression->u.double_value); 69 | yylval.Expression = expression; 70 | 71 | return DOUBLE_LITERAL; 72 | } 73 | \" { 74 | crb_open_string_literal(); 75 | BEGIN STRING_LITERAL_STATE; 76 | } 77 | 78 | # skip whitespace 79 | [ \t] ; 80 | \n {increment_line_number();} 81 | 82 | # 所有其它的字符都报错 83 | . { 84 | char buf[LINE_BUF_SIZE]; 85 | 86 | if (isprint(yytext[0])) { 87 | buf[0] = yytext[0]; 88 | buf[1] = '\0'; 89 | } else { 90 | sprintf(buf, "0x%02x", (unsigned char)yytext[0]); 91 | } 92 | 93 | crb_compile_error(CHARACTER_INVALID_ERR, 94 | STRING_MESSAGE_ARGUMENT, 95 | "bad_char", 96 | buf, 97 | MESSAGE_ARGUMENT_END); 98 | } 99 | 100 | \n { 101 | increment_line_number(); 102 | BEGIN INITIAL; 103 | } 104 | 105 | . ; 106 | 107 | \" { 108 | Expression *Expression = crb_alloc_expression(STRING_EXPRESSION); 109 | Expression->u.string_value = crb_close_string_literal(); 110 | yylval.expression = expression; 111 | BEGIN INITIAL; 112 | return STRING_LITERAL; 113 | } 114 | 115 | \n { 116 | crb_add_string_literal('\n'); 117 | increment_line_number(); 118 | } 119 | 120 | \\\" crb_add_string_literal('"'); 121 | \\n crb_add_string_literal('\n'); 122 | \\t crb_add_string_literal('\t'); 123 | \\\\ crb_add_string_literal('\\'); 124 | . crb_add_string_literal(yytext[0]); 125 | %% 126 | -------------------------------------------------------------------------------- /crowbar.y: -------------------------------------------------------------------------------- 1 | %{ 2 | #include 3 | #include "crowbar.h" 4 | #define YYDEBUG 1 5 | %} 6 | 7 | %union { 8 | char *identifier; 9 | ParameterList *parameter_list; 10 | ArgumentList *argument_list; 11 | Expression *expression; 12 | Statement *statement; 13 | StatementList *statement_list; 14 | Block *block; 15 | Elsif *elsif; 16 | IdentifierList *identifier_list; 17 | } 18 | 19 | %token INT_LITERAL 20 | %token DOUBLE_LITERAL 21 | %token STRING_LITERAL 22 | %token IDENTIFIER 23 | %token FUNCTION IF ELSE ELSIF WHILE FOR RETURN_T BREAK CONTINUE NULL_T 24 | LP RP LC RC SEMICOLON COMMA ASSIGN LOGICAL_AND LOGICAL_OR 25 | EQ NE GT GE LT LE ADD SUB MUL DIV MOD TRUE_T FALSE_T GLOBAL_T 26 | %type parameter_list 27 | %type argument_list 28 | %type expression expression_opt 29 | logical_and_expression logical_or_expression 30 | equality_expression relational_expression 31 | additive_expression multiplicative_expression 32 | unary_expression primary_expression 33 | %type statement global_statement 34 | if_statement while_statement for_statement 35 | return_statement break_statement continue_statement 36 | %type statement_list 37 | %type block 38 | %type elsif elsif_list 39 | %type identifier_list 40 | %% 41 | 42 | translation_unit 43 | : definition_or_statement 44 | | translation_unit definition_or_statement 45 | ; 46 | 47 | definition_or_statement 48 | : function_definition 49 | | statement 50 | { 51 | CRB_Interpreter *inter = crb_get_current_interpreter(); 52 | inter->statement_list = crb_chain_statement_list(inter->statement_list, $1); 53 | } 54 | ; 55 | 56 | function_definition 57 | : FUNCTION IDENTIFIER LP parameter_list RP block 58 | { 59 | crb_function_define($2, $4, $6); 60 | } 61 | | FUNCTION IDENTIFIER LP RP block 62 | { 63 | crb_function_define($2, NULL, $5); 64 | } 65 | ; 66 | 67 | parameter_list 68 | : IDENTIFIER 69 | { 70 | $$ = crb_create_parameter($1); 71 | } 72 | | argument_list COMMA expression 73 | { 74 | $$ = crb_chain_parameter($1, $3); 75 | } 76 | ; 77 | 78 | argument_list 79 | : expression 80 | { 81 | $$ = crb_create_argument_list($1); 82 | } 83 | | argument_list COMMA expression 84 | { 85 | $$ = crb_chain_argument_list($1, $3); 86 | } 87 | ; 88 | 89 | statement_list 90 | : statement 91 | { 92 | $$ = crb_create_statement_list($1); 93 | } 94 | | statement_list statement 95 | { 96 | $$ = crb_chain_statement($1, $2); 97 | } 98 | ; 99 | 100 | expression 101 | : logical_or_expression 102 | | IDENTIFIER ASSIGN expression 103 | { 104 | $$ = crb_create_assign_expression($1, $3); 105 | } 106 | ; 107 | 108 | logical_or_expression 109 | : logical_and_expression 110 | | logical_or_expression LOGICAL_OR logical_and_expression 111 | { 112 | $$ = crb_create_binary_expression(LOGICAL_OR_EXPRESSION, $1, $3); 113 | } 114 | ; 115 | 116 | logical_and_expression 117 | : equality_expression 118 | | logical_and_expression LOGICAL_AND equality_expression 119 | { 120 | $$ = crb_create_binary_expression(LOGCIAL_AND_EXPERSSION, $1, $3); 121 | } 122 | ; 123 | 124 | equality_expression 125 | : relational_expression 126 | | equality_expression EQ relational_expression 127 | { 128 | $$ = crb_create_binary_expression(EQ_EXPRESSION, $1, $3); 129 | } 130 | | equality_expression NE relational_expression 131 | { 132 | $$ = crb_create_binary_expression(NE_EXPRESSION, $1, $3); 133 | } 134 | ; 135 | 136 | relational_expression 137 | : additive_expression 138 | | relational_expression GT additive_expression 139 | { 140 | $$ = crb_create_binary_expression(GT_EXPRESSION, $1, $3); 141 | } 142 | | relational_expression GE additive_expression 143 | { 144 | $$ = crb_create_binary_expression(GE_EXPRESSION, $1, $3); 145 | } 146 | | relational_expression LT additive_expression 147 | { 148 | $$ = crb_create_binary_expression(LT_EXPRESSION, $1, $3); 149 | } 150 | | relational_expression LE additive_expression 151 | { 152 | $$ = crb_create_binary_expression(LE_EXPRESSION, $1, $3); 153 | } 154 | ; 155 | 156 | additive_expression 157 | : multiplicative_expression 158 | | additive_expression ADD multiplicative_expression 159 | { 160 | $$ = crb_create_binary_expression(ADD_EXPRESSION, $1, $3); 161 | } 162 | | additive_expression SUB multiplicative_expression 163 | { 164 | $$ = crb_create_binary_expression(SUB_EXPRESSION, $1, $3); 165 | } 166 | ; 167 | 168 | multiplicative_expression 169 | : unary_expression 170 | | multiplicative_expression MUL unary_expression 171 | { 172 | $$ = crb_create_binary_expression(MUL_EXPRESSION, $1, $3); 173 | } 174 | | multiplicative_expression DIV unary_expression 175 | { 176 | $$ = crb_create_binary_expression(DIV_EXPRESSION, $1, $3); 177 | } 178 | | multiplicative_expression MOD unary_expression 179 | { 180 | $$ = crb_create_binary_expression(MOD_EXPRESSION, $1, $3); 181 | } 182 | ; 183 | 184 | unary_expression 185 | : primary_expression 186 | | SUB unary_expression 187 | { 188 | $$ = crb_create_minus_experssion($2); 189 | } 190 | ; 191 | 192 | primary_expression 193 | : IDENTIFIER LP argument_list RP 194 | { 195 | $$ = crb_create_function_call_expression($1, $3); 196 | } 197 | | IDENTIFIER LP RP 198 | { 199 | $$ = crb_create_function_call_expression($1, NULL); 200 | } 201 | | LP expression RP 202 | { 203 | $$ = $2; 204 | } 205 | | IDENTIFIER 206 | { 207 | $$ = crb_create_identifier_expression($1); 208 | } 209 | | INT_LITERAL 210 | | DOUBLE_LITERAL 211 | | STRING_LITERAL 212 | | TRUE_T 213 | { 214 | $$ = crb_create_boolean_expression(CRB_TRUE); 215 | } 216 | | FALSE_T 217 | { 218 | $$ = crb_create_boolean_expression(CRB_FALSE); 219 | } 220 | | NULL_T 221 | { 222 | $$ = crb_create_null_expression(); 223 | } 224 | ; 225 | 226 | statement 227 | : expression SEMICOLON 228 | { 229 | $$ = crb_create_expression_statement($1); 230 | } 231 | | global_statement 232 | | if_statement 233 | | while_statement 234 | | for_statement 235 | | return_statement 236 | | break_statement 237 | | continue_statement 238 | ; 239 | 240 | global_statement 241 | : GLOBAL_T identifier_list SEMICOLON 242 | { 243 | $$ = crb_create_global_statement($2); 244 | } 245 | ; 246 | 247 | identifier_list 248 | : IDENTIFIER 249 | { 250 | $$ = crb_create_global_identifier($1); 251 | } 252 | | identifier_list COMMA IDENTIFIER 253 | { 254 | $$ = crb_chain_identifier($1, $3); 255 | } 256 | ; 257 | 258 | if_statement 259 | : IF LP expression RP block 260 | { 261 | $$ = crb_create_if_statement($3, $5, NULL, NULL); 262 | } 263 | | IF LP expression RP block ELSE block 264 | { 265 | $$ = crb_create_if_statement($3, $5, NULL, $7); 266 | } 267 | | IF LP expression RP block elsif_list 268 | { 269 | $$ = crb_create_if_statement($3, $5, $6, NULL); 270 | } 271 | | IF LP expression RP block elsif_list ELSE block 272 | { 273 | $$ = crb_create_if_statement($3, $5, $6, $8); 274 | } 275 | ; 276 | 277 | elsif_list 278 | : elsif 279 | | elsif_list elsif 280 | { 281 | $$ = crb_chain_elsif_list($1, $2); 282 | } 283 | ; 284 | 285 | elsif 286 | : ELSIF LP expression RP block 287 | { 288 | $$ = crb_create_elsif($3, $5); 289 | } 290 | ; 291 | 292 | 293 | while_statement 294 | : WHILE LP expression RP block 295 | { 296 | $$ = crb_create_while_statement($3, $5); 297 | } 298 | ; 299 | 300 | for_statement 301 | : FOR LP expression_opt SEMICOLON expression_opt SEMICOLON 302 | expression_opt RP block 303 | { 304 | $$ = crb_create_for_statement($3, $5, $7, $9); 305 | } 306 | ; 307 | 308 | expression_opt 309 | : 310 | { 311 | $$ = NULL; 312 | } 313 | | expression 314 | ; 315 | 316 | return_statement 317 | : RETURN_T expression_opt SEMICOLON 318 | { 319 | $$ = crb_create_return_statement($2); 320 | } 321 | ; 322 | 323 | 324 | break_statement 325 | : BREAK SEMICOLON 326 | { 327 | $$ = crb_create_break_statement(); 328 | } 329 | ; 330 | 331 | continue_statement 332 | : CONTINUE SEMICOLON 333 | { 334 | $$ = crb_create_continue_statement(); 335 | } 336 | ; 337 | 338 | block 339 | : LC statement_list RC 340 | { 341 | $$ = crb_create_block($2); 342 | } 343 | | LC RC 344 | { 345 | $$ = crb_create_block(NULL); 346 | } 347 | ; 348 | 349 | %% 350 | -------------------------------------------------------------------------------- /debug/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = dbg.o 2 | CC=gcc 3 | CFLAGS = -c -g -Wall -DDBG_NO_DEBUG -ansi -pedantic 4 | OBJS = debug.o 5 | INCLUDES = -I.. 6 | 7 | $(TARGET):$(OBJS) 8 | ld -r -o $@ $(OBJS) 9 | 10 | .c.o: 11 | $(CC) $(CFLAGS) $(INCLUDES) $*.c 12 | 13 | debug.o: debug.c ../MEM.h debug.h ../DBG.h 14 | 15 | clean: 16 | rm *.o 17 | -------------------------------------------------------------------------------- /debug/debug.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* include 这个为了使用 INT_MAX */ 3 | #include 4 | #include 5 | #include "MEM.h" 6 | #include "debug.h" 7 | 8 | static DBG_Controller st_current_controller; 9 | static char *st_current_file_name; 10 | static int st_current_line; 11 | static char *st_assert_expression; 12 | 13 | static struct DBG_Controller_tag st_default_controller = { 14 | NULL, 15 | INT_MAX 16 | }; 17 | 18 | DBG_Controller dbg_default_controller = &st_default_controller; 19 | 20 | DBG_Controller 21 | DBG_create_controller_func(void) 22 | { 23 | DBG_Controller controller; 24 | 25 | controller = MEM_malloc(sizeof(struct DBG_Controller_tag)); 26 | controller->debug_write_fp = NULL; 27 | controller->current_debug_level = INT_MAX; 28 | 29 | return controller; 30 | } 31 | 32 | void 33 | DBG_set_debug_level_func(DBG_Controller controller, int level) 34 | { 35 | controller->current_debug_level = level; 36 | } 37 | 38 | void 39 | DBG_set_debug_write_fp_func(DBG_Controller controller, FILE *p) 40 | { 41 | controller->debug_write_fp = p; 42 | } 43 | 44 | void 45 | DBG_set_expression(char *expression) 46 | { 47 | st_assert_expression = expression; 48 | } 49 | 50 | void 51 | DBG_set(DBG_Controller controller, char *file, int line) 52 | { 53 | st_current_controller = controller; 54 | st_current_file_name = file; 55 | st_current_line = line; 56 | } 57 | 58 | static 59 | void initialize_debug_write_fp(void) 60 | { 61 | if (st_default_controller.debug_write_fp == NULL) { 62 | st_default_controller.debug_write_fp = stderr; 63 | } 64 | } 65 | 66 | static void 67 | assert_func(FILE *fp, char *file, int line, char *expression, 68 | char *fmt, va_list ap) 69 | { 70 | fprintf(fp, "Assertion failure (%s) file..%s line..%d\n", 71 | expression, file, line); 72 | 73 | if (fmt) { 74 | vfprintf(fp, fmt, ap); 75 | } 76 | } 77 | 78 | void 79 | DBG_assert_func(char *fmt, ...) 80 | { 81 | va_list ap; 82 | va_start(ap, fmt); 83 | initialize_debug_write_fp(); 84 | assert_func(st_current_controller->debug_write_fp, 85 | st_current_file_name, st_current_line, 86 | st_assert_expression, fmt, ap); 87 | assert_func(stderr, 88 | st_current_file_name, st_current_line, 89 | st_assert_expression, fmt, ap); 90 | 91 | va_end(ap); 92 | abort(); 93 | } 94 | 95 | static void 96 | panic_func(FILE *fp, char *file, int line, char *fmt, va_list ap) 97 | { 98 | fprintf(fp, "Panic !! file..%s line..%d\n", file, line); 99 | if (fmt) { 100 | vfprintf(fp, fmt, ap); 101 | } 102 | } 103 | 104 | void 105 | DBG_debug_write_func(int level, char *fmt, ...) 106 | { 107 | va_list ap; 108 | 109 | if (level > 0 && level > st_current_controller->current_debug_level) { 110 | return; 111 | } 112 | va_start(ap, fmt); 113 | initialize_debug_write_fp(); 114 | if (fmt) { 115 | vfprintf(st_current_controller->debug_write_fp, fmt, ap); 116 | } 117 | va_end(ap); 118 | } 119 | -------------------------------------------------------------------------------- /debug/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef PRIVATE_DBG_H_INCLUDED 2 | #define PRIVATE_DBG_H_INCLUDED 3 | #include 4 | #include "DBG.h" 5 | struct DBG_Controller_tag { 6 | /* debug 信息写到哪里去 */ 7 | FILE *debug_write_fp; 8 | /* 当前的 debug level? 可能的值是哪些? */ 9 | int current_debug_level; 10 | }; 11 | 12 | #endif /* PRIVATE_DBG_H_INCLUDED */ 13 | -------------------------------------------------------------------------------- /eval.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "MEM.h" 4 | #include "DBG.h" 5 | #include "crowbar.h" 6 | 7 | CRB_Value crb_eval_binary_expression(CRB_Interpreter *inter, 8 | LocalEnvironment *env, 9 | ExpressionType operator, 10 | Expression *left, 11 | Expression *right) 12 | { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /lex.yy.c: -------------------------------------------------------------------------------- 1 | 2 | #line 3 "lex.yy.c" 3 | 4 | #define YY_INT_ALIGNED short int 5 | 6 | /* A lexical scanner generated by flex */ 7 | 8 | #define FLEX_SCANNER 9 | #define YY_FLEX_MAJOR_VERSION 2 10 | #define YY_FLEX_MINOR_VERSION 5 11 | #define YY_FLEX_SUBMINOR_VERSION 35 12 | #if YY_FLEX_SUBMINOR_VERSION > 0 13 | #define FLEX_BETA 14 | #endif 15 | 16 | /* First, we deal with platform-specific or compiler-specific issues. */ 17 | 18 | /* begin standard C headers. */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | /* end standard C headers. */ 25 | 26 | /* flex integer type definitions */ 27 | 28 | #ifndef FLEXINT_H 29 | #define FLEXINT_H 30 | 31 | /* C99 systems have . Non-C99 systems may or may not. */ 32 | 33 | #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 34 | 35 | /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, 36 | * if you want the limit (max/min) macros for int types. 37 | */ 38 | #ifndef __STDC_LIMIT_MACROS 39 | #define __STDC_LIMIT_MACROS 1 40 | #endif 41 | 42 | #include 43 | typedef int8_t flex_int8_t; 44 | typedef uint8_t flex_uint8_t; 45 | typedef int16_t flex_int16_t; 46 | typedef uint16_t flex_uint16_t; 47 | typedef int32_t flex_int32_t; 48 | typedef uint32_t flex_uint32_t; 49 | typedef uint64_t flex_uint64_t; 50 | #else 51 | typedef signed char flex_int8_t; 52 | typedef short int flex_int16_t; 53 | typedef int flex_int32_t; 54 | typedef unsigned char flex_uint8_t; 55 | typedef unsigned short int flex_uint16_t; 56 | typedef unsigned int flex_uint32_t; 57 | #endif /* ! C99 */ 58 | 59 | /* Limits of integral types. */ 60 | #ifndef INT8_MIN 61 | #define INT8_MIN (-128) 62 | #endif 63 | #ifndef INT16_MIN 64 | #define INT16_MIN (-32767-1) 65 | #endif 66 | #ifndef INT32_MIN 67 | #define INT32_MIN (-2147483647-1) 68 | #endif 69 | #ifndef INT8_MAX 70 | #define INT8_MAX (127) 71 | #endif 72 | #ifndef INT16_MAX 73 | #define INT16_MAX (32767) 74 | #endif 75 | #ifndef INT32_MAX 76 | #define INT32_MAX (2147483647) 77 | #endif 78 | #ifndef UINT8_MAX 79 | #define UINT8_MAX (255U) 80 | #endif 81 | #ifndef UINT16_MAX 82 | #define UINT16_MAX (65535U) 83 | #endif 84 | #ifndef UINT32_MAX 85 | #define UINT32_MAX (4294967295U) 86 | #endif 87 | 88 | #endif /* ! FLEXINT_H */ 89 | 90 | #ifdef __cplusplus 91 | 92 | /* The "const" storage-class-modifier is valid. */ 93 | #define YY_USE_CONST 94 | 95 | #else /* ! __cplusplus */ 96 | 97 | /* C99 requires __STDC__ to be defined as 1. */ 98 | #if defined (__STDC__) 99 | 100 | #define YY_USE_CONST 101 | 102 | #endif /* defined (__STDC__) */ 103 | #endif /* ! __cplusplus */ 104 | 105 | #ifdef YY_USE_CONST 106 | #define yyconst const 107 | #else 108 | #define yyconst 109 | #endif 110 | 111 | /* Returned upon end-of-file. */ 112 | #define YY_NULL 0 113 | 114 | /* Promotes a possibly negative, possibly signed char to an unsigned 115 | * integer for use as an array index. If the signed char is negative, 116 | * we want to instead treat it as an 8-bit unsigned char, hence the 117 | * double cast. 118 | */ 119 | #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) 120 | 121 | /* Enter a start condition. This macro really ought to take a parameter, 122 | * but we do it the disgusting crufty way forced on us by the ()-less 123 | * definition of BEGIN. 124 | */ 125 | #define BEGIN (yy_start) = 1 + 2 * 126 | 127 | /* Translate the current start state into a value that can be later handed 128 | * to BEGIN to return to the state. The YYSTATE alias is for lex 129 | * compatibility. 130 | */ 131 | #define YY_START (((yy_start) - 1) / 2) 132 | #define YYSTATE YY_START 133 | 134 | /* Action number for EOF rule of a given start state. */ 135 | #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) 136 | 137 | /* Special action meaning "start processing a new file". */ 138 | #define YY_NEW_FILE yyrestart(yyin ) 139 | 140 | #define YY_END_OF_BUFFER_CHAR 0 141 | 142 | /* Size of default input buffer. */ 143 | #ifndef YY_BUF_SIZE 144 | #define YY_BUF_SIZE 16384 145 | #endif 146 | 147 | /* The state buf must be large enough to hold one state per character in the main buffer. 148 | */ 149 | #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) 150 | 151 | #ifndef YY_TYPEDEF_YY_BUFFER_STATE 152 | #define YY_TYPEDEF_YY_BUFFER_STATE 153 | typedef struct yy_buffer_state *YY_BUFFER_STATE; 154 | #endif 155 | 156 | #ifndef YY_TYPEDEF_YY_SIZE_T 157 | #define YY_TYPEDEF_YY_SIZE_T 158 | typedef size_t yy_size_t; 159 | #endif 160 | 161 | extern yy_size_t yyleng; 162 | 163 | extern FILE *yyin, *yyout; 164 | 165 | #define EOB_ACT_CONTINUE_SCAN 0 166 | #define EOB_ACT_END_OF_FILE 1 167 | #define EOB_ACT_LAST_MATCH 2 168 | 169 | #define YY_LESS_LINENO(n) 170 | 171 | /* Return all but the first "n" matched characters back to the input stream. */ 172 | #define yyless(n) \ 173 | do \ 174 | { \ 175 | /* Undo effects of setting up yytext. */ \ 176 | int yyless_macro_arg = (n); \ 177 | YY_LESS_LINENO(yyless_macro_arg);\ 178 | *yy_cp = (yy_hold_char); \ 179 | YY_RESTORE_YY_MORE_OFFSET \ 180 | (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ 181 | YY_DO_BEFORE_ACTION; /* set up yytext again */ \ 182 | } \ 183 | while ( 0 ) 184 | 185 | #define unput(c) yyunput( c, (yytext_ptr) ) 186 | 187 | #ifndef YY_STRUCT_YY_BUFFER_STATE 188 | #define YY_STRUCT_YY_BUFFER_STATE 189 | struct yy_buffer_state 190 | { 191 | FILE *yy_input_file; 192 | 193 | char *yy_ch_buf; /* input buffer */ 194 | char *yy_buf_pos; /* current position in input buffer */ 195 | 196 | /* Size of input buffer in bytes, not including room for EOB 197 | * characters. 198 | */ 199 | yy_size_t yy_buf_size; 200 | 201 | /* Number of characters read into yy_ch_buf, not including EOB 202 | * characters. 203 | */ 204 | yy_size_t yy_n_chars; 205 | 206 | /* Whether we "own" the buffer - i.e., we know we created it, 207 | * and can realloc() it to grow it, and should free() it to 208 | * delete it. 209 | */ 210 | int yy_is_our_buffer; 211 | 212 | /* Whether this is an "interactive" input source; if so, and 213 | * if we're using stdio for input, then we want to use getc() 214 | * instead of fread(), to make sure we stop fetching input after 215 | * each newline. 216 | */ 217 | int yy_is_interactive; 218 | 219 | /* Whether we're considered to be at the beginning of a line. 220 | * If so, '^' rules will be active on the next match, otherwise 221 | * not. 222 | */ 223 | int yy_at_bol; 224 | 225 | int yy_bs_lineno; /**< The line count. */ 226 | int yy_bs_column; /**< The column count. */ 227 | 228 | /* Whether to try to fill the input buffer when we reach the 229 | * end of it. 230 | */ 231 | int yy_fill_buffer; 232 | 233 | int yy_buffer_status; 234 | 235 | #define YY_BUFFER_NEW 0 236 | #define YY_BUFFER_NORMAL 1 237 | /* When an EOF's been seen but there's still some text to process 238 | * then we mark the buffer as YY_EOF_PENDING, to indicate that we 239 | * shouldn't try reading from the input source any more. We might 240 | * still have a bunch of tokens to match, though, because of 241 | * possible backing-up. 242 | * 243 | * When we actually see the EOF, we change the status to "new" 244 | * (via yyrestart()), so that the user can continue scanning by 245 | * just pointing yyin at a new input file. 246 | */ 247 | #define YY_BUFFER_EOF_PENDING 2 248 | 249 | }; 250 | #endif /* !YY_STRUCT_YY_BUFFER_STATE */ 251 | 252 | /* Stack of input buffers. */ 253 | static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ 254 | static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ 255 | static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ 256 | 257 | /* We provide macros for accessing buffer states in case in the 258 | * future we want to put the buffer states in a more general 259 | * "scanner state". 260 | * 261 | * Returns the top of the stack, or NULL. 262 | */ 263 | #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ 264 | ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ 265 | : NULL) 266 | 267 | /* Same as previous macro, but useful when we know that the buffer stack is not 268 | * NULL or when we need an lvalue. For internal use only. 269 | */ 270 | #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] 271 | 272 | /* yy_hold_char holds the character lost when yytext is formed. */ 273 | static char yy_hold_char; 274 | static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ 275 | yy_size_t yyleng; 276 | 277 | /* Points to current character in buffer. */ 278 | static char *yy_c_buf_p = (char *) 0; 279 | static int yy_init = 0; /* whether we need to initialize */ 280 | static int yy_start = 0; /* start state number */ 281 | 282 | /* Flag which is used to allow yywrap()'s to do buffer switches 283 | * instead of setting up a fresh yyin. A bit of a hack ... 284 | */ 285 | static int yy_did_buffer_switch_on_eof; 286 | 287 | void yyrestart (FILE *input_file ); 288 | void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); 289 | YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); 290 | void yy_delete_buffer (YY_BUFFER_STATE b ); 291 | void yy_flush_buffer (YY_BUFFER_STATE b ); 292 | void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); 293 | void yypop_buffer_state (void ); 294 | 295 | static void yyensure_buffer_stack (void ); 296 | static void yy_load_buffer_state (void ); 297 | static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); 298 | 299 | #define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) 300 | 301 | YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); 302 | YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); 303 | YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); 304 | 305 | void *yyalloc (yy_size_t ); 306 | void *yyrealloc (void *,yy_size_t ); 307 | void yyfree (void * ); 308 | 309 | #define yy_new_buffer yy_create_buffer 310 | 311 | #define yy_set_interactive(is_interactive) \ 312 | { \ 313 | if ( ! YY_CURRENT_BUFFER ){ \ 314 | yyensure_buffer_stack (); \ 315 | YY_CURRENT_BUFFER_LVALUE = \ 316 | yy_create_buffer(yyin,YY_BUF_SIZE ); \ 317 | } \ 318 | YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ 319 | } 320 | 321 | #define yy_set_bol(at_bol) \ 322 | { \ 323 | if ( ! YY_CURRENT_BUFFER ){\ 324 | yyensure_buffer_stack (); \ 325 | YY_CURRENT_BUFFER_LVALUE = \ 326 | yy_create_buffer(yyin,YY_BUF_SIZE ); \ 327 | } \ 328 | YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ 329 | } 330 | 331 | #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) 332 | 333 | /* Begin user sect3 */ 334 | 335 | typedef unsigned char YY_CHAR; 336 | 337 | FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; 338 | 339 | typedef int yy_state_type; 340 | 341 | extern int yylineno; 342 | 343 | int yylineno = 1; 344 | 345 | extern char *yytext; 346 | #define yytext_ptr yytext 347 | 348 | static yy_state_type yy_get_previous_state (void ); 349 | static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); 350 | static int yy_get_next_buffer (void ); 351 | static void yy_fatal_error (yyconst char msg[] ); 352 | 353 | /* Done after the current pattern has been matched and before the 354 | * corresponding action - sets up yytext. 355 | */ 356 | #define YY_DO_BEFORE_ACTION \ 357 | (yytext_ptr) = yy_bp; \ 358 | yyleng = (yy_size_t) (yy_cp - yy_bp); \ 359 | (yy_hold_char) = *yy_cp; \ 360 | *yy_cp = '\0'; \ 361 | (yy_c_buf_p) = yy_cp; 362 | 363 | #define YY_NUM_RULES 52 364 | #define YY_END_OF_BUFFER 53 365 | /* This struct is not used in this scanner, 366 | but its presence is necessary. */ 367 | struct yy_trans_info 368 | { 369 | flex_int32_t yy_verify; 370 | flex_int32_t yy_nxt; 371 | }; 372 | static yyconst flex_int16_t yy_accept[117] = 373 | { 0, 374 | 0, 0, 0, 0, 0, 0, 53, 42, 39, 40, 375 | 42, 37, 38, 33, 42, 14, 15, 31, 29, 19, 376 | 30, 32, 35, 35, 18, 27, 22, 25, 34, 34, 377 | 34, 34, 34, 34, 34, 34, 34, 34, 34, 16, 378 | 42, 17, 44, 43, 38, 51, 46, 45, 38, 51, 379 | 24, 20, 0, 0, 35, 28, 23, 26, 34, 34, 380 | 34, 34, 34, 34, 34, 34, 2, 34, 34, 34, 381 | 34, 21, 47, 50, 48, 49, 36, 34, 34, 34, 382 | 34, 6, 34, 34, 34, 34, 34, 34, 34, 34, 383 | 3, 34, 34, 34, 34, 10, 34, 11, 34, 8, 384 | 385 | 34, 4, 12, 34, 34, 34, 5, 34, 34, 13, 386 | 7, 34, 34, 9, 1, 0 387 | } ; 388 | 389 | static yyconst flex_int32_t yy_ec[256] = 390 | { 0, 391 | 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 392 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 393 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 394 | 1, 2, 4, 5, 6, 1, 7, 8, 1, 9, 395 | 10, 11, 12, 13, 14, 15, 16, 17, 18, 18, 396 | 18, 18, 18, 18, 18, 18, 18, 1, 19, 20, 397 | 21, 22, 1, 1, 23, 23, 23, 23, 23, 23, 398 | 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 399 | 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 400 | 1, 24, 1, 1, 23, 1, 25, 26, 27, 23, 401 | 402 | 28, 29, 30, 31, 32, 23, 33, 34, 23, 35, 403 | 36, 23, 23, 37, 38, 39, 40, 23, 41, 23, 404 | 23, 23, 42, 43, 44, 1, 1, 1, 1, 1, 405 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 406 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 407 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 408 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 409 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 410 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 411 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 412 | 413 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 414 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 415 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 416 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 417 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 418 | 1, 1, 1, 1, 1 419 | } ; 420 | 421 | static yyconst flex_int32_t yy_meta[45] = 422 | { 0, 423 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 424 | 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 425 | 1, 1, 2, 1, 2, 2, 2, 2, 2, 2, 426 | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 427 | 2, 1, 1, 1 428 | } ; 429 | 430 | static yyconst flex_int16_t yy_base[120] = 431 | { 0, 432 | 0, 0, 42, 43, 47, 51, 138, 139, 139, 139, 433 | 116, 139, 139, 139, 128, 139, 139, 139, 139, 139, 434 | 139, 139, 43, 47, 139, 114, 113, 112, 0, 95, 435 | 95, 96, 30, 95, 99, 87, 98, 88, 93, 139, 436 | 80, 139, 139, 139, 139, 139, 139, 139, 139, 54, 437 | 139, 139, 50, 59, 64, 139, 139, 139, 0, 94, 438 | 86, 82, 85, 81, 82, 80, 0, 81, 75, 73, 439 | 80, 139, 139, 139, 139, 139, 55, 86, 71, 19, 440 | 71, 0, 81, 81, 72, 65, 76, 69, 69, 69, 441 | 0, 71, 71, 59, 67, 0, 54, 0, 62, 0, 442 | 443 | 53, 0, 0, 55, 52, 50, 0, 44, 47, 0, 444 | 0, 52, 34, 0, 0, 139, 93, 95, 61 445 | } ; 446 | 447 | static yyconst flex_int16_t yy_def[120] = 448 | { 0, 449 | 116, 1, 117, 117, 118, 118, 116, 116, 116, 116, 450 | 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 451 | 116, 116, 116, 116, 116, 116, 116, 116, 119, 119, 452 | 119, 119, 119, 119, 119, 119, 119, 119, 119, 116, 453 | 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 454 | 116, 116, 116, 116, 116, 116, 116, 116, 119, 119, 455 | 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 456 | 119, 116, 116, 116, 116, 116, 116, 119, 119, 119, 457 | 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 458 | 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 459 | 460 | 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 461 | 119, 119, 119, 119, 119, 0, 116, 116, 116 462 | } ; 463 | 464 | static yyconst flex_int16_t yy_nxt[184] = 465 | { 0, 466 | 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 467 | 18, 19, 20, 21, 8, 22, 23, 24, 25, 26, 468 | 27, 28, 29, 8, 29, 30, 31, 32, 33, 34, 469 | 29, 35, 29, 29, 36, 29, 37, 29, 38, 29, 470 | 39, 40, 41, 42, 44, 44, 91, 45, 45, 47, 471 | 92, 48, 49, 47, 63, 48, 49, 53, 73, 54, 472 | 54, 53, 59, 55, 55, 64, 77, 77, 115, 65, 473 | 50, 77, 77, 53, 50, 54, 54, 74, 53, 114, 474 | 55, 55, 113, 112, 111, 110, 109, 108, 75, 107, 475 | 106, 105, 76, 43, 43, 46, 46, 104, 103, 102, 476 | 477 | 101, 100, 99, 98, 97, 96, 95, 94, 93, 90, 478 | 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 479 | 79, 78, 72, 71, 70, 69, 68, 67, 66, 62, 480 | 61, 60, 58, 57, 56, 52, 51, 116, 7, 116, 481 | 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 482 | 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 483 | 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 484 | 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 485 | 116, 116, 116 486 | } ; 487 | 488 | static yyconst flex_int16_t yy_chk[184] = 489 | { 0, 490 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 491 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 492 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 493 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 494 | 1, 1, 1, 1, 3, 4, 80, 3, 4, 5, 495 | 80, 5, 5, 6, 33, 6, 6, 23, 50, 23, 496 | 23, 24, 119, 24, 24, 33, 53, 53, 113, 33, 497 | 5, 77, 77, 54, 6, 54, 54, 50, 55, 112, 498 | 55, 55, 109, 108, 106, 105, 104, 101, 50, 99, 499 | 97, 95, 50, 117, 117, 118, 118, 94, 93, 92, 500 | 501 | 90, 89, 88, 87, 86, 85, 84, 83, 81, 79, 502 | 78, 71, 70, 69, 68, 66, 65, 64, 63, 62, 503 | 61, 60, 41, 39, 38, 37, 36, 35, 34, 32, 504 | 31, 30, 28, 27, 26, 15, 11, 7, 116, 116, 505 | 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 506 | 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 507 | 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 508 | 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 509 | 116, 116, 116 510 | } ; 511 | 512 | static yy_state_type yy_last_accepting_state; 513 | static char *yy_last_accepting_cpos; 514 | 515 | extern int yy_flex_debug; 516 | int yy_flex_debug = 0; 517 | 518 | /* The intent behind this definition is that it'll catch 519 | * any uses of REJECT which flex missed. 520 | */ 521 | #define REJECT reject_used_but_not_detected 522 | #define yymore() yymore_used_but_not_detected 523 | #define YY_MORE_ADJ 0 524 | #define YY_RESTORE_YY_MORE_OFFSET 525 | char *yytext; 526 | #line 1 "crowbar.l" 527 | #line 2 "crowbar.l" 528 | #include 529 | #include 530 | #include "DBG.h" 531 | #include "crowbar.h" 532 | #include "y.tab.h" 533 | 534 | int 535 | yywrap(void) 536 | { 537 | return 1; 538 | } 539 | 540 | static void 541 | increment_line_number(void) 542 | { 543 | crb_get_current_interpreter()->current_line_number++; 544 | } 545 | 546 | #line 547 "lex.yy.c" 547 | 548 | #define INITIAL 0 549 | #define COMMENT 1 550 | #define STRING_LITERAL_STATE 2 551 | 552 | #ifndef YY_NO_UNISTD_H 553 | /* Special case for "unistd.h", since it is non-ANSI. We include it way 554 | * down here because we want the user's section 1 to have been scanned first. 555 | * The user has a chance to override it with an option. 556 | */ 557 | #include 558 | #endif 559 | 560 | #ifndef YY_EXTRA_TYPE 561 | #define YY_EXTRA_TYPE void * 562 | #endif 563 | 564 | static int yy_init_globals (void ); 565 | 566 | /* Accessor methods to globals. 567 | These are made visible to non-reentrant scanners for convenience. */ 568 | 569 | int yylex_destroy (void ); 570 | 571 | int yyget_debug (void ); 572 | 573 | void yyset_debug (int debug_flag ); 574 | 575 | YY_EXTRA_TYPE yyget_extra (void ); 576 | 577 | void yyset_extra (YY_EXTRA_TYPE user_defined ); 578 | 579 | FILE *yyget_in (void ); 580 | 581 | void yyset_in (FILE * in_str ); 582 | 583 | FILE *yyget_out (void ); 584 | 585 | void yyset_out (FILE * out_str ); 586 | 587 | yy_size_t yyget_leng (void ); 588 | 589 | char *yyget_text (void ); 590 | 591 | int yyget_lineno (void ); 592 | 593 | void yyset_lineno (int line_number ); 594 | 595 | /* Macros after this point can all be overridden by user definitions in 596 | * section 1. 597 | */ 598 | 599 | #ifndef YY_SKIP_YYWRAP 600 | #ifdef __cplusplus 601 | extern "C" int yywrap (void ); 602 | #else 603 | extern int yywrap (void ); 604 | #endif 605 | #endif 606 | 607 | static void yyunput (int c,char *buf_ptr ); 608 | 609 | #ifndef yytext_ptr 610 | static void yy_flex_strncpy (char *,yyconst char *,int ); 611 | #endif 612 | 613 | #ifdef YY_NEED_STRLEN 614 | static int yy_flex_strlen (yyconst char * ); 615 | #endif 616 | 617 | #ifndef YY_NO_INPUT 618 | 619 | #ifdef __cplusplus 620 | static int yyinput (void ); 621 | #else 622 | static int input (void ); 623 | #endif 624 | 625 | #endif 626 | 627 | /* Amount of stuff to slurp up with each read. */ 628 | #ifndef YY_READ_BUF_SIZE 629 | #define YY_READ_BUF_SIZE 8192 630 | #endif 631 | 632 | /* Copy whatever the last rule matched to the standard output. */ 633 | #ifndef ECHO 634 | /* This used to be an fputs(), but since the string might contain NUL's, 635 | * we now use fwrite(). 636 | */ 637 | #define ECHO fwrite( yytext, yyleng, 1, yyout ) 638 | #endif 639 | 640 | /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, 641 | * is returned in "result". 642 | */ 643 | #ifndef YY_INPUT 644 | #define YY_INPUT(buf,result,max_size) \ 645 | if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ 646 | { \ 647 | int c = '*'; \ 648 | yy_size_t n; \ 649 | for ( n = 0; n < max_size && \ 650 | (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ 651 | buf[n] = (char) c; \ 652 | if ( c == '\n' ) \ 653 | buf[n++] = (char) c; \ 654 | if ( c == EOF && ferror( yyin ) ) \ 655 | YY_FATAL_ERROR( "input in flex scanner failed" ); \ 656 | result = n; \ 657 | } \ 658 | else \ 659 | { \ 660 | errno=0; \ 661 | while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ 662 | { \ 663 | if( errno != EINTR) \ 664 | { \ 665 | YY_FATAL_ERROR( "input in flex scanner failed" ); \ 666 | break; \ 667 | } \ 668 | errno=0; \ 669 | clearerr(yyin); \ 670 | } \ 671 | }\ 672 | \ 673 | 674 | #endif 675 | 676 | /* No semi-colon after return; correct usage is to write "yyterminate();" - 677 | * we don't want an extra ';' after the "return" because that will cause 678 | * some compilers to complain about unreachable statements. 679 | */ 680 | #ifndef yyterminate 681 | #define yyterminate() return YY_NULL 682 | #endif 683 | 684 | /* Number of entries by which start-condition stack grows. */ 685 | #ifndef YY_START_STACK_INCR 686 | #define YY_START_STACK_INCR 25 687 | #endif 688 | 689 | /* Report a fatal error. */ 690 | #ifndef YY_FATAL_ERROR 691 | #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) 692 | #endif 693 | 694 | /* end tables serialization structures and prototypes */ 695 | 696 | /* Default declaration of generated scanner - a define so the user can 697 | * easily add parameters. 698 | */ 699 | #ifndef YY_DECL 700 | #define YY_DECL_IS_OURS 1 701 | 702 | extern int yylex (void); 703 | 704 | #define YY_DECL int yylex (void) 705 | #endif /* !YY_DECL */ 706 | 707 | /* Code executed at the beginning of each rule, after yytext and yyleng 708 | * have been set up. 709 | */ 710 | #ifndef YY_USER_ACTION 711 | #define YY_USER_ACTION 712 | #endif 713 | 714 | /* Code executed at the end of each rule. */ 715 | #ifndef YY_BREAK 716 | #define YY_BREAK break; 717 | #endif 718 | 719 | #define YY_RULE_SETUP \ 720 | YY_USER_ACTION 721 | 722 | /** The main scanner function which does all the work. 723 | */ 724 | YY_DECL 725 | { 726 | register yy_state_type yy_current_state; 727 | register char *yy_cp, *yy_bp; 728 | register int yy_act; 729 | 730 | #line 22 "crowbar.l" 731 | 732 | #line 733 "lex.yy.c" 733 | 734 | if ( !(yy_init) ) 735 | { 736 | (yy_init) = 1; 737 | 738 | #ifdef YY_USER_INIT 739 | YY_USER_INIT; 740 | #endif 741 | 742 | if ( ! (yy_start) ) 743 | (yy_start) = 1; /* first start state */ 744 | 745 | if ( ! yyin ) 746 | yyin = stdin; 747 | 748 | if ( ! yyout ) 749 | yyout = stdout; 750 | 751 | if ( ! YY_CURRENT_BUFFER ) { 752 | yyensure_buffer_stack (); 753 | YY_CURRENT_BUFFER_LVALUE = 754 | yy_create_buffer(yyin,YY_BUF_SIZE ); 755 | } 756 | 757 | yy_load_buffer_state( ); 758 | } 759 | 760 | while ( 1 ) /* loops until end-of-file is reached */ 761 | { 762 | yy_cp = (yy_c_buf_p); 763 | 764 | /* Support of yytext. */ 765 | *yy_cp = (yy_hold_char); 766 | 767 | /* yy_bp points to the position in yy_ch_buf of the start of 768 | * the current run. 769 | */ 770 | yy_bp = yy_cp; 771 | 772 | yy_current_state = (yy_start); 773 | yy_match: 774 | do 775 | { 776 | register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; 777 | if ( yy_accept[yy_current_state] ) 778 | { 779 | (yy_last_accepting_state) = yy_current_state; 780 | (yy_last_accepting_cpos) = yy_cp; 781 | } 782 | while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 783 | { 784 | yy_current_state = (int) yy_def[yy_current_state]; 785 | if ( yy_current_state >= 117 ) 786 | yy_c = yy_meta[(unsigned int) yy_c]; 787 | } 788 | yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 789 | ++yy_cp; 790 | } 791 | while ( yy_base[yy_current_state] != 139 ); 792 | 793 | yy_find_action: 794 | yy_act = yy_accept[yy_current_state]; 795 | if ( yy_act == 0 ) 796 | { /* have to back up */ 797 | yy_cp = (yy_last_accepting_cpos); 798 | yy_current_state = (yy_last_accepting_state); 799 | yy_act = yy_accept[yy_current_state]; 800 | } 801 | 802 | YY_DO_BEFORE_ACTION; 803 | 804 | do_action: /* This label is used only to access EOF actions. */ 805 | 806 | switch ( yy_act ) 807 | { /* beginning of action switch */ 808 | case 0: /* must back up */ 809 | /* undo the effects of YY_DO_BEFORE_ACTION */ 810 | *yy_cp = (yy_hold_char); 811 | yy_cp = (yy_last_accepting_cpos); 812 | yy_current_state = (yy_last_accepting_state); 813 | goto yy_find_action; 814 | 815 | case 1: 816 | YY_RULE_SETUP 817 | #line 23 "crowbar.l" 818 | return FUNCTION; 819 | YY_BREAK 820 | case 2: 821 | YY_RULE_SETUP 822 | #line 24 "crowbar.l" 823 | return IF; 824 | YY_BREAK 825 | case 3: 826 | YY_RULE_SETUP 827 | #line 25 "crowbar.l" 828 | return ELSE; 829 | YY_BREAK 830 | case 4: 831 | YY_RULE_SETUP 832 | #line 26 "crowbar.l" 833 | return ELSIF; 834 | YY_BREAK 835 | case 5: 836 | YY_RULE_SETUP 837 | #line 27 "crowbar.l" 838 | return WHILE; 839 | YY_BREAK 840 | case 6: 841 | YY_RULE_SETUP 842 | #line 28 "crowbar.l" 843 | return FOR; 844 | YY_BREAK 845 | case 7: 846 | YY_RULE_SETUP 847 | #line 29 "crowbar.l" 848 | return RETURN_T; 849 | YY_BREAK 850 | case 8: 851 | YY_RULE_SETUP 852 | #line 30 "crowbar.l" 853 | return BREAK; 854 | YY_BREAK 855 | case 9: 856 | YY_RULE_SETUP 857 | #line 31 "crowbar.l" 858 | return CONTINUE; 859 | YY_BREAK 860 | case 10: 861 | YY_RULE_SETUP 862 | #line 32 "crowbar.l" 863 | return NULL_T; 864 | YY_BREAK 865 | case 11: 866 | YY_RULE_SETUP 867 | #line 33 "crowbar.l" 868 | return TRUE_T; 869 | YY_BREAK 870 | case 12: 871 | YY_RULE_SETUP 872 | #line 34 "crowbar.l" 873 | return FALSE_T; 874 | YY_BREAK 875 | case 13: 876 | YY_RULE_SETUP 877 | #line 35 "crowbar.l" 878 | return GLOBAL_T; 879 | YY_BREAK 880 | case 14: 881 | YY_RULE_SETUP 882 | #line 36 "crowbar.l" 883 | return LP; 884 | YY_BREAK 885 | case 15: 886 | YY_RULE_SETUP 887 | #line 37 "crowbar.l" 888 | return RP; 889 | YY_BREAK 890 | case 16: 891 | YY_RULE_SETUP 892 | #line 38 "crowbar.l" 893 | return LC; 894 | YY_BREAK 895 | case 17: 896 | YY_RULE_SETUP 897 | #line 39 "crowbar.l" 898 | return RC; 899 | YY_BREAK 900 | case 18: 901 | YY_RULE_SETUP 902 | #line 40 "crowbar.l" 903 | return SEMICOLON; 904 | YY_BREAK 905 | case 19: 906 | YY_RULE_SETUP 907 | #line 41 "crowbar.l" 908 | return COMMA; 909 | YY_BREAK 910 | case 20: 911 | YY_RULE_SETUP 912 | #line 42 "crowbar.l" 913 | return LOGICAL_AND; 914 | YY_BREAK 915 | case 21: 916 | YY_RULE_SETUP 917 | #line 43 "crowbar.l" 918 | return LOGICAL_OR; 919 | YY_BREAK 920 | case 22: 921 | YY_RULE_SETUP 922 | #line 44 "crowbar.l" 923 | return ASSIGN; 924 | YY_BREAK 925 | case 23: 926 | YY_RULE_SETUP 927 | #line 45 "crowbar.l" 928 | return EQ; 929 | YY_BREAK 930 | case 24: 931 | YY_RULE_SETUP 932 | #line 46 "crowbar.l" 933 | return NE; 934 | YY_BREAK 935 | case 25: 936 | YY_RULE_SETUP 937 | #line 47 "crowbar.l" 938 | return GT; 939 | YY_BREAK 940 | case 26: 941 | YY_RULE_SETUP 942 | #line 48 "crowbar.l" 943 | return GE; 944 | YY_BREAK 945 | case 27: 946 | YY_RULE_SETUP 947 | #line 49 "crowbar.l" 948 | return LT; 949 | YY_BREAK 950 | case 28: 951 | YY_RULE_SETUP 952 | #line 50 "crowbar.l" 953 | return LE; 954 | YY_BREAK 955 | case 29: 956 | YY_RULE_SETUP 957 | #line 51 "crowbar.l" 958 | return ADD; 959 | YY_BREAK 960 | case 30: 961 | YY_RULE_SETUP 962 | #line 52 "crowbar.l" 963 | return SUB; 964 | YY_BREAK 965 | case 31: 966 | YY_RULE_SETUP 967 | #line 53 "crowbar.l" 968 | return MUL; 969 | YY_BREAK 970 | case 32: 971 | YY_RULE_SETUP 972 | #line 54 "crowbar.l" 973 | return DIV; 974 | YY_BREAK 975 | case 33: 976 | YY_RULE_SETUP 977 | #line 55 "crowbar.l" 978 | return MOD; 979 | YY_BREAK 980 | case 34: 981 | YY_RULE_SETUP 982 | #line 56 "crowbar.l" 983 | { 984 | yylval.identifier = crb_create_identifier(yytext); 985 | return IDENTIFIER; 986 | } 987 | YY_BREAK 988 | case 35: 989 | YY_RULE_SETUP 990 | #line 60 "crowbar.l" 991 | { 992 | Expression *expression = crb_alloc_expression(INT_EXPRESSION); 993 | sscanf(yytext, "%d", &expression->u.int_value); 994 | yylval.expression = expression; 995 | return INT_LITERAL; 996 | } 997 | YY_BREAK 998 | case 36: 999 | YY_RULE_SETUP 1000 | #line 66 "crowbar.l" 1001 | { 1002 | Expression *Expression = crb_alloc_expression(DOUBLE_EXPRESSION); 1003 | sscanf(yytext, "%lf", &expression->u.double_value); 1004 | yylval.Expression = expression; 1005 | 1006 | return DOUBLE_LITERAL; 1007 | } 1008 | YY_BREAK 1009 | case 37: 1010 | YY_RULE_SETUP 1011 | #line 73 "crowbar.l" 1012 | { 1013 | crb_open_string_literal(); 1014 | BEGIN STRING_LITERAL_STATE; 1015 | } 1016 | YY_BREAK 1017 | case 38: 1018 | YY_RULE_SETUP 1019 | #line 78 "crowbar.l" 1020 | skip whitespace 1021 | YY_BREAK 1022 | case 39: 1023 | YY_RULE_SETUP 1024 | #line 79 "crowbar.l" 1025 | ; 1026 | YY_BREAK 1027 | case 40: 1028 | /* rule 40 can match eol */ 1029 | YY_RULE_SETUP 1030 | #line 80 "crowbar.l" 1031 | {increment_line_number();} 1032 | YY_BREAK 1033 | case 41: 1034 | YY_RULE_SETUP 1035 | #line 82 "crowbar.l" 1036 | 所有其它的字符都报错 1037 | YY_BREAK 1038 | case 42: 1039 | YY_RULE_SETUP 1040 | #line 83 "crowbar.l" 1041 | { 1042 | char buf[LINE_BUF_SIZE]; 1043 | 1044 | if (isprint(yytext[0])) { 1045 | buf[0] = yytext[0]; 1046 | buf[1] = '\0'; 1047 | } else { 1048 | sprintf(buf, "0x%02x", (unsigned char)yytext[0]); 1049 | } 1050 | 1051 | crb_compile_error(CHARACTER_INVALID_ERR, 1052 | STRING_MESSAGE_ARGUMENT, 1053 | "bad_char", 1054 | buf, 1055 | MESSAGE_ARGUMENT_END); 1056 | } 1057 | YY_BREAK 1058 | case 43: 1059 | /* rule 43 can match eol */ 1060 | YY_RULE_SETUP 1061 | #line 100 "crowbar.l" 1062 | { 1063 | increment_line_number(); 1064 | BEGIN INITIAL; 1065 | } 1066 | YY_BREAK 1067 | case 44: 1068 | YY_RULE_SETUP 1069 | #line 105 "crowbar.l" 1070 | ; 1071 | YY_BREAK 1072 | case 45: 1073 | YY_RULE_SETUP 1074 | #line 107 "crowbar.l" 1075 | { 1076 | Expression *Expression = crb_alloc_expression(STRING_EXPRESSION); 1077 | Expression->u.string_value = crb_close_string_literal(); 1078 | yylval.expression = expression; 1079 | BEGIN INITIAL; 1080 | return STRING_LITERAL; 1081 | } 1082 | YY_BREAK 1083 | case 46: 1084 | /* rule 46 can match eol */ 1085 | YY_RULE_SETUP 1086 | #line 115 "crowbar.l" 1087 | { 1088 | crb_add_string_literal('\n'); 1089 | increment_line_number(); 1090 | } 1091 | YY_BREAK 1092 | case 47: 1093 | YY_RULE_SETUP 1094 | #line 120 "crowbar.l" 1095 | crb_add_string_literal('"'); 1096 | YY_BREAK 1097 | case 48: 1098 | YY_RULE_SETUP 1099 | #line 121 "crowbar.l" 1100 | crb_add_string_literal('\n'); 1101 | YY_BREAK 1102 | case 49: 1103 | YY_RULE_SETUP 1104 | #line 122 "crowbar.l" 1105 | crb_add_string_literal('\t'); 1106 | YY_BREAK 1107 | case 50: 1108 | YY_RULE_SETUP 1109 | #line 123 "crowbar.l" 1110 | crb_add_string_literal('\\'); 1111 | YY_BREAK 1112 | case 51: 1113 | YY_RULE_SETUP 1114 | #line 124 "crowbar.l" 1115 | crb_add_string_literal(yytext[0]); 1116 | YY_BREAK 1117 | case 52: 1118 | YY_RULE_SETUP 1119 | #line 125 "crowbar.l" 1120 | ECHO; 1121 | YY_BREAK 1122 | #line 1123 "lex.yy.c" 1123 | case YY_STATE_EOF(INITIAL): 1124 | case YY_STATE_EOF(COMMENT): 1125 | case YY_STATE_EOF(STRING_LITERAL_STATE): 1126 | yyterminate(); 1127 | 1128 | case YY_END_OF_BUFFER: 1129 | { 1130 | /* Amount of text matched not including the EOB char. */ 1131 | int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; 1132 | 1133 | /* Undo the effects of YY_DO_BEFORE_ACTION. */ 1134 | *yy_cp = (yy_hold_char); 1135 | YY_RESTORE_YY_MORE_OFFSET 1136 | 1137 | if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) 1138 | { 1139 | /* We're scanning a new file or input source. It's 1140 | * possible that this happened because the user 1141 | * just pointed yyin at a new source and called 1142 | * yylex(). If so, then we have to assure 1143 | * consistency between YY_CURRENT_BUFFER and our 1144 | * globals. Here is the right place to do so, because 1145 | * this is the first action (other than possibly a 1146 | * back-up) that will match for the new input source. 1147 | */ 1148 | (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; 1149 | YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; 1150 | YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; 1151 | } 1152 | 1153 | /* Note that here we test for yy_c_buf_p "<=" to the position 1154 | * of the first EOB in the buffer, since yy_c_buf_p will 1155 | * already have been incremented past the NUL character 1156 | * (since all states make transitions on EOB to the 1157 | * end-of-buffer state). Contrast this with the test 1158 | * in input(). 1159 | */ 1160 | if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) 1161 | { /* This was really a NUL. */ 1162 | yy_state_type yy_next_state; 1163 | 1164 | (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; 1165 | 1166 | yy_current_state = yy_get_previous_state( ); 1167 | 1168 | /* Okay, we're now positioned to make the NUL 1169 | * transition. We couldn't have 1170 | * yy_get_previous_state() go ahead and do it 1171 | * for us because it doesn't know how to deal 1172 | * with the possibility of jamming (and we don't 1173 | * want to build jamming into it because then it 1174 | * will run more slowly). 1175 | */ 1176 | 1177 | yy_next_state = yy_try_NUL_trans( yy_current_state ); 1178 | 1179 | yy_bp = (yytext_ptr) + YY_MORE_ADJ; 1180 | 1181 | if ( yy_next_state ) 1182 | { 1183 | /* Consume the NUL. */ 1184 | yy_cp = ++(yy_c_buf_p); 1185 | yy_current_state = yy_next_state; 1186 | goto yy_match; 1187 | } 1188 | 1189 | else 1190 | { 1191 | yy_cp = (yy_c_buf_p); 1192 | goto yy_find_action; 1193 | } 1194 | } 1195 | 1196 | else switch ( yy_get_next_buffer( ) ) 1197 | { 1198 | case EOB_ACT_END_OF_FILE: 1199 | { 1200 | (yy_did_buffer_switch_on_eof) = 0; 1201 | 1202 | if ( yywrap( ) ) 1203 | { 1204 | /* Note: because we've taken care in 1205 | * yy_get_next_buffer() to have set up 1206 | * yytext, we can now set up 1207 | * yy_c_buf_p so that if some total 1208 | * hoser (like flex itself) wants to 1209 | * call the scanner after we return the 1210 | * YY_NULL, it'll still work - another 1211 | * YY_NULL will get returned. 1212 | */ 1213 | (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; 1214 | 1215 | yy_act = YY_STATE_EOF(YY_START); 1216 | goto do_action; 1217 | } 1218 | 1219 | else 1220 | { 1221 | if ( ! (yy_did_buffer_switch_on_eof) ) 1222 | YY_NEW_FILE; 1223 | } 1224 | break; 1225 | } 1226 | 1227 | case EOB_ACT_CONTINUE_SCAN: 1228 | (yy_c_buf_p) = 1229 | (yytext_ptr) + yy_amount_of_matched_text; 1230 | 1231 | yy_current_state = yy_get_previous_state( ); 1232 | 1233 | yy_cp = (yy_c_buf_p); 1234 | yy_bp = (yytext_ptr) + YY_MORE_ADJ; 1235 | goto yy_match; 1236 | 1237 | case EOB_ACT_LAST_MATCH: 1238 | (yy_c_buf_p) = 1239 | &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; 1240 | 1241 | yy_current_state = yy_get_previous_state( ); 1242 | 1243 | yy_cp = (yy_c_buf_p); 1244 | yy_bp = (yytext_ptr) + YY_MORE_ADJ; 1245 | goto yy_find_action; 1246 | } 1247 | break; 1248 | } 1249 | 1250 | default: 1251 | YY_FATAL_ERROR( 1252 | "fatal flex scanner internal error--no action found" ); 1253 | } /* end of action switch */ 1254 | } /* end of scanning one token */ 1255 | } /* end of yylex */ 1256 | 1257 | /* yy_get_next_buffer - try to read in a new buffer 1258 | * 1259 | * Returns a code representing an action: 1260 | * EOB_ACT_LAST_MATCH - 1261 | * EOB_ACT_CONTINUE_SCAN - continue scanning from current position 1262 | * EOB_ACT_END_OF_FILE - end of file 1263 | */ 1264 | static int yy_get_next_buffer (void) 1265 | { 1266 | register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; 1267 | register char *source = (yytext_ptr); 1268 | register int number_to_move, i; 1269 | int ret_val; 1270 | 1271 | if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) 1272 | YY_FATAL_ERROR( 1273 | "fatal flex scanner internal error--end of buffer missed" ); 1274 | 1275 | if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) 1276 | { /* Don't try to fill the buffer, so this is an EOF. */ 1277 | if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) 1278 | { 1279 | /* We matched a single character, the EOB, so 1280 | * treat this as a final EOF. 1281 | */ 1282 | return EOB_ACT_END_OF_FILE; 1283 | } 1284 | 1285 | else 1286 | { 1287 | /* We matched some text prior to the EOB, first 1288 | * process it. 1289 | */ 1290 | return EOB_ACT_LAST_MATCH; 1291 | } 1292 | } 1293 | 1294 | /* Try to read more data. */ 1295 | 1296 | /* First move last chars to start of buffer. */ 1297 | number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; 1298 | 1299 | for ( i = 0; i < number_to_move; ++i ) 1300 | *(dest++) = *(source++); 1301 | 1302 | if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) 1303 | /* don't do the read, it's not guaranteed to return an EOF, 1304 | * just force an EOF 1305 | */ 1306 | YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; 1307 | 1308 | else 1309 | { 1310 | yy_size_t num_to_read = 1311 | YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; 1312 | 1313 | while ( num_to_read <= 0 ) 1314 | { /* Not enough room in the buffer - grow it. */ 1315 | 1316 | /* just a shorter name for the current buffer */ 1317 | YY_BUFFER_STATE b = YY_CURRENT_BUFFER; 1318 | 1319 | int yy_c_buf_p_offset = 1320 | (int) ((yy_c_buf_p) - b->yy_ch_buf); 1321 | 1322 | if ( b->yy_is_our_buffer ) 1323 | { 1324 | yy_size_t new_size = b->yy_buf_size * 2; 1325 | 1326 | if ( new_size <= 0 ) 1327 | b->yy_buf_size += b->yy_buf_size / 8; 1328 | else 1329 | b->yy_buf_size *= 2; 1330 | 1331 | b->yy_ch_buf = (char *) 1332 | /* Include room in for 2 EOB chars. */ 1333 | yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); 1334 | } 1335 | else 1336 | /* Can't grow it, we don't own it. */ 1337 | b->yy_ch_buf = 0; 1338 | 1339 | if ( ! b->yy_ch_buf ) 1340 | YY_FATAL_ERROR( 1341 | "fatal error - scanner input buffer overflow" ); 1342 | 1343 | (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; 1344 | 1345 | num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - 1346 | number_to_move - 1; 1347 | 1348 | } 1349 | 1350 | if ( num_to_read > YY_READ_BUF_SIZE ) 1351 | num_to_read = YY_READ_BUF_SIZE; 1352 | 1353 | /* Read in more data. */ 1354 | YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), 1355 | (yy_n_chars), num_to_read ); 1356 | 1357 | YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); 1358 | } 1359 | 1360 | if ( (yy_n_chars) == 0 ) 1361 | { 1362 | if ( number_to_move == YY_MORE_ADJ ) 1363 | { 1364 | ret_val = EOB_ACT_END_OF_FILE; 1365 | yyrestart(yyin ); 1366 | } 1367 | 1368 | else 1369 | { 1370 | ret_val = EOB_ACT_LAST_MATCH; 1371 | YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = 1372 | YY_BUFFER_EOF_PENDING; 1373 | } 1374 | } 1375 | 1376 | else 1377 | ret_val = EOB_ACT_CONTINUE_SCAN; 1378 | 1379 | if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { 1380 | /* Extend the array by 50%, plus the number we really need. */ 1381 | yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); 1382 | YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); 1383 | if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) 1384 | YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); 1385 | } 1386 | 1387 | (yy_n_chars) += number_to_move; 1388 | YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; 1389 | YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; 1390 | 1391 | (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; 1392 | 1393 | return ret_val; 1394 | } 1395 | 1396 | /* yy_get_previous_state - get the state just before the EOB char was reached */ 1397 | 1398 | static yy_state_type yy_get_previous_state (void) 1399 | { 1400 | register yy_state_type yy_current_state; 1401 | register char *yy_cp; 1402 | 1403 | yy_current_state = (yy_start); 1404 | 1405 | for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) 1406 | { 1407 | register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); 1408 | if ( yy_accept[yy_current_state] ) 1409 | { 1410 | (yy_last_accepting_state) = yy_current_state; 1411 | (yy_last_accepting_cpos) = yy_cp; 1412 | } 1413 | while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 1414 | { 1415 | yy_current_state = (int) yy_def[yy_current_state]; 1416 | if ( yy_current_state >= 117 ) 1417 | yy_c = yy_meta[(unsigned int) yy_c]; 1418 | } 1419 | yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 1420 | } 1421 | 1422 | return yy_current_state; 1423 | } 1424 | 1425 | /* yy_try_NUL_trans - try to make a transition on the NUL character 1426 | * 1427 | * synopsis 1428 | * next_state = yy_try_NUL_trans( current_state ); 1429 | */ 1430 | static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) 1431 | { 1432 | register int yy_is_jam; 1433 | register char *yy_cp = (yy_c_buf_p); 1434 | 1435 | register YY_CHAR yy_c = 1; 1436 | if ( yy_accept[yy_current_state] ) 1437 | { 1438 | (yy_last_accepting_state) = yy_current_state; 1439 | (yy_last_accepting_cpos) = yy_cp; 1440 | } 1441 | while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 1442 | { 1443 | yy_current_state = (int) yy_def[yy_current_state]; 1444 | if ( yy_current_state >= 117 ) 1445 | yy_c = yy_meta[(unsigned int) yy_c]; 1446 | } 1447 | yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 1448 | yy_is_jam = (yy_current_state == 116); 1449 | 1450 | return yy_is_jam ? 0 : yy_current_state; 1451 | } 1452 | 1453 | static void yyunput (int c, register char * yy_bp ) 1454 | { 1455 | register char *yy_cp; 1456 | 1457 | yy_cp = (yy_c_buf_p); 1458 | 1459 | /* undo effects of setting up yytext */ 1460 | *yy_cp = (yy_hold_char); 1461 | 1462 | if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) 1463 | { /* need to shift things up to make room */ 1464 | /* +2 for EOB chars. */ 1465 | register yy_size_t number_to_move = (yy_n_chars) + 2; 1466 | register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ 1467 | YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; 1468 | register char *source = 1469 | &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; 1470 | 1471 | while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) 1472 | *--dest = *--source; 1473 | 1474 | yy_cp += (int) (dest - source); 1475 | yy_bp += (int) (dest - source); 1476 | YY_CURRENT_BUFFER_LVALUE->yy_n_chars = 1477 | (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; 1478 | 1479 | if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) 1480 | YY_FATAL_ERROR( "flex scanner push-back overflow" ); 1481 | } 1482 | 1483 | *--yy_cp = (char) c; 1484 | 1485 | (yytext_ptr) = yy_bp; 1486 | (yy_hold_char) = *yy_cp; 1487 | (yy_c_buf_p) = yy_cp; 1488 | } 1489 | 1490 | #ifndef YY_NO_INPUT 1491 | #ifdef __cplusplus 1492 | static int yyinput (void) 1493 | #else 1494 | static int input (void) 1495 | #endif 1496 | 1497 | { 1498 | int c; 1499 | 1500 | *(yy_c_buf_p) = (yy_hold_char); 1501 | 1502 | if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) 1503 | { 1504 | /* yy_c_buf_p now points to the character we want to return. 1505 | * If this occurs *before* the EOB characters, then it's a 1506 | * valid NUL; if not, then we've hit the end of the buffer. 1507 | */ 1508 | if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) 1509 | /* This was really a NUL. */ 1510 | *(yy_c_buf_p) = '\0'; 1511 | 1512 | else 1513 | { /* need more input */ 1514 | yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); 1515 | ++(yy_c_buf_p); 1516 | 1517 | switch ( yy_get_next_buffer( ) ) 1518 | { 1519 | case EOB_ACT_LAST_MATCH: 1520 | /* This happens because yy_g_n_b() 1521 | * sees that we've accumulated a 1522 | * token and flags that we need to 1523 | * try matching the token before 1524 | * proceeding. But for input(), 1525 | * there's no matching to consider. 1526 | * So convert the EOB_ACT_LAST_MATCH 1527 | * to EOB_ACT_END_OF_FILE. 1528 | */ 1529 | 1530 | /* Reset buffer status. */ 1531 | yyrestart(yyin ); 1532 | 1533 | /*FALLTHROUGH*/ 1534 | 1535 | case EOB_ACT_END_OF_FILE: 1536 | { 1537 | if ( yywrap( ) ) 1538 | return 0; 1539 | 1540 | if ( ! (yy_did_buffer_switch_on_eof) ) 1541 | YY_NEW_FILE; 1542 | #ifdef __cplusplus 1543 | return yyinput(); 1544 | #else 1545 | return input(); 1546 | #endif 1547 | } 1548 | 1549 | case EOB_ACT_CONTINUE_SCAN: 1550 | (yy_c_buf_p) = (yytext_ptr) + offset; 1551 | break; 1552 | } 1553 | } 1554 | } 1555 | 1556 | c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ 1557 | *(yy_c_buf_p) = '\0'; /* preserve yytext */ 1558 | (yy_hold_char) = *++(yy_c_buf_p); 1559 | 1560 | return c; 1561 | } 1562 | #endif /* ifndef YY_NO_INPUT */ 1563 | 1564 | /** Immediately switch to a different input stream. 1565 | * @param input_file A readable stream. 1566 | * 1567 | * @note This function does not reset the start condition to @c INITIAL . 1568 | */ 1569 | void yyrestart (FILE * input_file ) 1570 | { 1571 | 1572 | if ( ! YY_CURRENT_BUFFER ){ 1573 | yyensure_buffer_stack (); 1574 | YY_CURRENT_BUFFER_LVALUE = 1575 | yy_create_buffer(yyin,YY_BUF_SIZE ); 1576 | } 1577 | 1578 | yy_init_buffer(YY_CURRENT_BUFFER,input_file ); 1579 | yy_load_buffer_state( ); 1580 | } 1581 | 1582 | /** Switch to a different input buffer. 1583 | * @param new_buffer The new input buffer. 1584 | * 1585 | */ 1586 | void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) 1587 | { 1588 | 1589 | /* TODO. We should be able to replace this entire function body 1590 | * with 1591 | * yypop_buffer_state(); 1592 | * yypush_buffer_state(new_buffer); 1593 | */ 1594 | yyensure_buffer_stack (); 1595 | if ( YY_CURRENT_BUFFER == new_buffer ) 1596 | return; 1597 | 1598 | if ( YY_CURRENT_BUFFER ) 1599 | { 1600 | /* Flush out information for old buffer. */ 1601 | *(yy_c_buf_p) = (yy_hold_char); 1602 | YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); 1603 | YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); 1604 | } 1605 | 1606 | YY_CURRENT_BUFFER_LVALUE = new_buffer; 1607 | yy_load_buffer_state( ); 1608 | 1609 | /* We don't actually know whether we did this switch during 1610 | * EOF (yywrap()) processing, but the only time this flag 1611 | * is looked at is after yywrap() is called, so it's safe 1612 | * to go ahead and always set it. 1613 | */ 1614 | (yy_did_buffer_switch_on_eof) = 1; 1615 | } 1616 | 1617 | static void yy_load_buffer_state (void) 1618 | { 1619 | (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; 1620 | (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; 1621 | yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; 1622 | (yy_hold_char) = *(yy_c_buf_p); 1623 | } 1624 | 1625 | /** Allocate and initialize an input buffer state. 1626 | * @param file A readable stream. 1627 | * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. 1628 | * 1629 | * @return the allocated buffer state. 1630 | */ 1631 | YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) 1632 | { 1633 | YY_BUFFER_STATE b; 1634 | 1635 | b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); 1636 | if ( ! b ) 1637 | YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); 1638 | 1639 | b->yy_buf_size = size; 1640 | 1641 | /* yy_ch_buf has to be 2 characters longer than the size given because 1642 | * we need to put in 2 end-of-buffer characters. 1643 | */ 1644 | b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); 1645 | if ( ! b->yy_ch_buf ) 1646 | YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); 1647 | 1648 | b->yy_is_our_buffer = 1; 1649 | 1650 | yy_init_buffer(b,file ); 1651 | 1652 | return b; 1653 | } 1654 | 1655 | /** Destroy the buffer. 1656 | * @param b a buffer created with yy_create_buffer() 1657 | * 1658 | */ 1659 | void yy_delete_buffer (YY_BUFFER_STATE b ) 1660 | { 1661 | 1662 | if ( ! b ) 1663 | return; 1664 | 1665 | if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ 1666 | YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; 1667 | 1668 | if ( b->yy_is_our_buffer ) 1669 | yyfree((void *) b->yy_ch_buf ); 1670 | 1671 | yyfree((void *) b ); 1672 | } 1673 | 1674 | #ifndef __cplusplus 1675 | extern int isatty (int ); 1676 | #endif /* __cplusplus */ 1677 | 1678 | /* Initializes or reinitializes a buffer. 1679 | * This function is sometimes called more than once on the same buffer, 1680 | * such as during a yyrestart() or at EOF. 1681 | */ 1682 | static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) 1683 | 1684 | { 1685 | int oerrno = errno; 1686 | 1687 | yy_flush_buffer(b ); 1688 | 1689 | b->yy_input_file = file; 1690 | b->yy_fill_buffer = 1; 1691 | 1692 | /* If b is the current buffer, then yy_init_buffer was _probably_ 1693 | * called from yyrestart() or through yy_get_next_buffer. 1694 | * In that case, we don't want to reset the lineno or column. 1695 | */ 1696 | if (b != YY_CURRENT_BUFFER){ 1697 | b->yy_bs_lineno = 1; 1698 | b->yy_bs_column = 0; 1699 | } 1700 | 1701 | b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; 1702 | 1703 | errno = oerrno; 1704 | } 1705 | 1706 | /** Discard all buffered characters. On the next scan, YY_INPUT will be called. 1707 | * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. 1708 | * 1709 | */ 1710 | void yy_flush_buffer (YY_BUFFER_STATE b ) 1711 | { 1712 | if ( ! b ) 1713 | return; 1714 | 1715 | b->yy_n_chars = 0; 1716 | 1717 | /* We always need two end-of-buffer characters. The first causes 1718 | * a transition to the end-of-buffer state. The second causes 1719 | * a jam in that state. 1720 | */ 1721 | b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; 1722 | b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; 1723 | 1724 | b->yy_buf_pos = &b->yy_ch_buf[0]; 1725 | 1726 | b->yy_at_bol = 1; 1727 | b->yy_buffer_status = YY_BUFFER_NEW; 1728 | 1729 | if ( b == YY_CURRENT_BUFFER ) 1730 | yy_load_buffer_state( ); 1731 | } 1732 | 1733 | /** Pushes the new state onto the stack. The new state becomes 1734 | * the current state. This function will allocate the stack 1735 | * if necessary. 1736 | * @param new_buffer The new state. 1737 | * 1738 | */ 1739 | void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) 1740 | { 1741 | if (new_buffer == NULL) 1742 | return; 1743 | 1744 | yyensure_buffer_stack(); 1745 | 1746 | /* This block is copied from yy_switch_to_buffer. */ 1747 | if ( YY_CURRENT_BUFFER ) 1748 | { 1749 | /* Flush out information for old buffer. */ 1750 | *(yy_c_buf_p) = (yy_hold_char); 1751 | YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); 1752 | YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); 1753 | } 1754 | 1755 | /* Only push if top exists. Otherwise, replace top. */ 1756 | if (YY_CURRENT_BUFFER) 1757 | (yy_buffer_stack_top)++; 1758 | YY_CURRENT_BUFFER_LVALUE = new_buffer; 1759 | 1760 | /* copied from yy_switch_to_buffer. */ 1761 | yy_load_buffer_state( ); 1762 | (yy_did_buffer_switch_on_eof) = 1; 1763 | } 1764 | 1765 | /** Removes and deletes the top of the stack, if present. 1766 | * The next element becomes the new top. 1767 | * 1768 | */ 1769 | void yypop_buffer_state (void) 1770 | { 1771 | if (!YY_CURRENT_BUFFER) 1772 | return; 1773 | 1774 | yy_delete_buffer(YY_CURRENT_BUFFER ); 1775 | YY_CURRENT_BUFFER_LVALUE = NULL; 1776 | if ((yy_buffer_stack_top) > 0) 1777 | --(yy_buffer_stack_top); 1778 | 1779 | if (YY_CURRENT_BUFFER) { 1780 | yy_load_buffer_state( ); 1781 | (yy_did_buffer_switch_on_eof) = 1; 1782 | } 1783 | } 1784 | 1785 | /* Allocates the stack if it does not exist. 1786 | * Guarantees space for at least one push. 1787 | */ 1788 | static void yyensure_buffer_stack (void) 1789 | { 1790 | yy_size_t num_to_alloc; 1791 | 1792 | if (!(yy_buffer_stack)) { 1793 | 1794 | /* First allocation is just for 2 elements, since we don't know if this 1795 | * scanner will even need a stack. We use 2 instead of 1 to avoid an 1796 | * immediate realloc on the next call. 1797 | */ 1798 | num_to_alloc = 1; 1799 | (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc 1800 | (num_to_alloc * sizeof(struct yy_buffer_state*) 1801 | ); 1802 | if ( ! (yy_buffer_stack) ) 1803 | YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); 1804 | 1805 | memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); 1806 | 1807 | (yy_buffer_stack_max) = num_to_alloc; 1808 | (yy_buffer_stack_top) = 0; 1809 | return; 1810 | } 1811 | 1812 | if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ 1813 | 1814 | /* Increase the buffer to prepare for a possible push. */ 1815 | int grow_size = 8 /* arbitrary grow size */; 1816 | 1817 | num_to_alloc = (yy_buffer_stack_max) + grow_size; 1818 | (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc 1819 | ((yy_buffer_stack), 1820 | num_to_alloc * sizeof(struct yy_buffer_state*) 1821 | ); 1822 | if ( ! (yy_buffer_stack) ) 1823 | YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); 1824 | 1825 | /* zero only the new slots.*/ 1826 | memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); 1827 | (yy_buffer_stack_max) = num_to_alloc; 1828 | } 1829 | } 1830 | 1831 | /** Setup the input buffer state to scan directly from a user-specified character buffer. 1832 | * @param base the character buffer 1833 | * @param size the size in bytes of the character buffer 1834 | * 1835 | * @return the newly allocated buffer state object. 1836 | */ 1837 | YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) 1838 | { 1839 | YY_BUFFER_STATE b; 1840 | 1841 | if ( size < 2 || 1842 | base[size-2] != YY_END_OF_BUFFER_CHAR || 1843 | base[size-1] != YY_END_OF_BUFFER_CHAR ) 1844 | /* They forgot to leave room for the EOB's. */ 1845 | return 0; 1846 | 1847 | b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); 1848 | if ( ! b ) 1849 | YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); 1850 | 1851 | b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ 1852 | b->yy_buf_pos = b->yy_ch_buf = base; 1853 | b->yy_is_our_buffer = 0; 1854 | b->yy_input_file = 0; 1855 | b->yy_n_chars = b->yy_buf_size; 1856 | b->yy_is_interactive = 0; 1857 | b->yy_at_bol = 1; 1858 | b->yy_fill_buffer = 0; 1859 | b->yy_buffer_status = YY_BUFFER_NEW; 1860 | 1861 | yy_switch_to_buffer(b ); 1862 | 1863 | return b; 1864 | } 1865 | 1866 | /** Setup the input buffer state to scan a string. The next call to yylex() will 1867 | * scan from a @e copy of @a str. 1868 | * @param yystr a NUL-terminated string to scan 1869 | * 1870 | * @return the newly allocated buffer state object. 1871 | * @note If you want to scan bytes that may contain NUL values, then use 1872 | * yy_scan_bytes() instead. 1873 | */ 1874 | YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) 1875 | { 1876 | 1877 | return yy_scan_bytes(yystr,strlen(yystr) ); 1878 | } 1879 | 1880 | /** Setup the input buffer state to scan the given bytes. The next call to yylex() will 1881 | * scan from a @e copy of @a bytes. 1882 | * @param bytes the byte buffer to scan 1883 | * @param len the number of bytes in the buffer pointed to by @a bytes. 1884 | * 1885 | * @return the newly allocated buffer state object. 1886 | */ 1887 | YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) 1888 | { 1889 | YY_BUFFER_STATE b; 1890 | char *buf; 1891 | yy_size_t n, i; 1892 | 1893 | /* Get memory for full buffer, including space for trailing EOB's. */ 1894 | n = _yybytes_len + 2; 1895 | buf = (char *) yyalloc(n ); 1896 | if ( ! buf ) 1897 | YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); 1898 | 1899 | for ( i = 0; i < _yybytes_len; ++i ) 1900 | buf[i] = yybytes[i]; 1901 | 1902 | buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; 1903 | 1904 | b = yy_scan_buffer(buf,n ); 1905 | if ( ! b ) 1906 | YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); 1907 | 1908 | /* It's okay to grow etc. this buffer, and we should throw it 1909 | * away when we're done. 1910 | */ 1911 | b->yy_is_our_buffer = 1; 1912 | 1913 | return b; 1914 | } 1915 | 1916 | #ifndef YY_EXIT_FAILURE 1917 | #define YY_EXIT_FAILURE 2 1918 | #endif 1919 | 1920 | static void yy_fatal_error (yyconst char* msg ) 1921 | { 1922 | (void) fprintf( stderr, "%s\n", msg ); 1923 | exit( YY_EXIT_FAILURE ); 1924 | } 1925 | 1926 | /* Redefine yyless() so it works in section 3 code. */ 1927 | 1928 | #undef yyless 1929 | #define yyless(n) \ 1930 | do \ 1931 | { \ 1932 | /* Undo effects of setting up yytext. */ \ 1933 | int yyless_macro_arg = (n); \ 1934 | YY_LESS_LINENO(yyless_macro_arg);\ 1935 | yytext[yyleng] = (yy_hold_char); \ 1936 | (yy_c_buf_p) = yytext + yyless_macro_arg; \ 1937 | (yy_hold_char) = *(yy_c_buf_p); \ 1938 | *(yy_c_buf_p) = '\0'; \ 1939 | yyleng = yyless_macro_arg; \ 1940 | } \ 1941 | while ( 0 ) 1942 | 1943 | /* Accessor methods (get/set functions) to struct members. */ 1944 | 1945 | /** Get the current line number. 1946 | * 1947 | */ 1948 | int yyget_lineno (void) 1949 | { 1950 | 1951 | return yylineno; 1952 | } 1953 | 1954 | /** Get the input stream. 1955 | * 1956 | */ 1957 | FILE *yyget_in (void) 1958 | { 1959 | return yyin; 1960 | } 1961 | 1962 | /** Get the output stream. 1963 | * 1964 | */ 1965 | FILE *yyget_out (void) 1966 | { 1967 | return yyout; 1968 | } 1969 | 1970 | /** Get the length of the current token. 1971 | * 1972 | */ 1973 | yy_size_t yyget_leng (void) 1974 | { 1975 | return yyleng; 1976 | } 1977 | 1978 | /** Get the current token. 1979 | * 1980 | */ 1981 | 1982 | char *yyget_text (void) 1983 | { 1984 | return yytext; 1985 | } 1986 | 1987 | /** Set the current line number. 1988 | * @param line_number 1989 | * 1990 | */ 1991 | void yyset_lineno (int line_number ) 1992 | { 1993 | 1994 | yylineno = line_number; 1995 | } 1996 | 1997 | /** Set the input stream. This does not discard the current 1998 | * input buffer. 1999 | * @param in_str A readable stream. 2000 | * 2001 | * @see yy_switch_to_buffer 2002 | */ 2003 | void yyset_in (FILE * in_str ) 2004 | { 2005 | yyin = in_str ; 2006 | } 2007 | 2008 | void yyset_out (FILE * out_str ) 2009 | { 2010 | yyout = out_str ; 2011 | } 2012 | 2013 | int yyget_debug (void) 2014 | { 2015 | return yy_flex_debug; 2016 | } 2017 | 2018 | void yyset_debug (int bdebug ) 2019 | { 2020 | yy_flex_debug = bdebug ; 2021 | } 2022 | 2023 | static int yy_init_globals (void) 2024 | { 2025 | /* Initialization is the same as for the non-reentrant scanner. 2026 | * This function is called from yylex_destroy(), so don't allocate here. 2027 | */ 2028 | 2029 | (yy_buffer_stack) = 0; 2030 | (yy_buffer_stack_top) = 0; 2031 | (yy_buffer_stack_max) = 0; 2032 | (yy_c_buf_p) = (char *) 0; 2033 | (yy_init) = 0; 2034 | (yy_start) = 0; 2035 | 2036 | /* Defined in main.c */ 2037 | #ifdef YY_STDINIT 2038 | yyin = stdin; 2039 | yyout = stdout; 2040 | #else 2041 | yyin = (FILE *) 0; 2042 | yyout = (FILE *) 0; 2043 | #endif 2044 | 2045 | /* For future reference: Set errno on error, since we are called by 2046 | * yylex_init() 2047 | */ 2048 | return 0; 2049 | } 2050 | 2051 | /* yylex_destroy is for both reentrant and non-reentrant scanners. */ 2052 | int yylex_destroy (void) 2053 | { 2054 | 2055 | /* Pop the buffer stack, destroying each element. */ 2056 | while(YY_CURRENT_BUFFER){ 2057 | yy_delete_buffer(YY_CURRENT_BUFFER ); 2058 | YY_CURRENT_BUFFER_LVALUE = NULL; 2059 | yypop_buffer_state(); 2060 | } 2061 | 2062 | /* Destroy the stack itself. */ 2063 | yyfree((yy_buffer_stack) ); 2064 | (yy_buffer_stack) = NULL; 2065 | 2066 | /* Reset the globals. This is important in a non-reentrant scanner so the next time 2067 | * yylex() is called, initialization will occur. */ 2068 | yy_init_globals( ); 2069 | 2070 | return 0; 2071 | } 2072 | 2073 | /* 2074 | * Internal utility routines. 2075 | */ 2076 | 2077 | #ifndef yytext_ptr 2078 | static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) 2079 | { 2080 | register int i; 2081 | for ( i = 0; i < n; ++i ) 2082 | s1[i] = s2[i]; 2083 | } 2084 | #endif 2085 | 2086 | #ifdef YY_NEED_STRLEN 2087 | static int yy_flex_strlen (yyconst char * s ) 2088 | { 2089 | register int n; 2090 | for ( n = 0; s[n]; ++n ) 2091 | ; 2092 | 2093 | return n; 2094 | } 2095 | #endif 2096 | 2097 | void *yyalloc (yy_size_t size ) 2098 | { 2099 | return (void *) malloc( size ); 2100 | } 2101 | 2102 | void *yyrealloc (void * ptr, yy_size_t size ) 2103 | { 2104 | /* The cast to (char *) in the following accommodates both 2105 | * implementations that use char* generic pointers, and those 2106 | * that use void* generic pointers. It works with the latter 2107 | * because both ANSI C and C++ allow castless assignment from 2108 | * any pointer type to void*, and deal with argument conversions 2109 | * as though doing an assignment. 2110 | */ 2111 | return (void *) realloc( (char *) ptr, size ); 2112 | } 2113 | 2114 | void yyfree (void * ptr ) 2115 | { 2116 | free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ 2117 | } 2118 | 2119 | #define YYTABLES_NAME "yytables" 2120 | 2121 | #line 125 "crowbar.l" 2122 | 2123 | 2124 | 2125 | -------------------------------------------------------------------------------- /memory/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS = -c -g -DDEBUG -Wall -ansi -pedantic -std=c99 3 | OBJS = memory.o storage.o 4 | TARGETS = test testp 5 | 6 | testp : ${OBJS} main.o 7 | $(CC) -o $@ main.o ${OBJS} 8 | .c.o: 9 | $(CC) $(CFLAGS) -I.. $*.c 10 | main.o: main.c ../MEM.h 11 | 12 | memory.o: memory.c memory.h ../MEM.h 13 | storage.o: storage.c memory.h ../MEM.h 14 | test: *_test.c ${OBJS} ../MEM.h 15 | ${CC} -I.. -o $@ *_test.c ${OBJS} 16 | ./$@ 17 | 18 | clean: 19 | rm -f *.o 20 | rm -f ${TARGETS} 21 | -------------------------------------------------------------------------------- /memory/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "MEM.h" 4 | 5 | static void 6 | dump_buffer(unsigned char *buf, int size) 7 | { 8 | int i; 9 | for (i = 0; i < size; i++) { 10 | printf("%02x ", buf[i]); 11 | if (i % 16 == 15) { 12 | printf("\n"); 13 | } 14 | } 15 | printf("\n"); 16 | } 17 | 18 | static void 19 | fill_buffer(unsigned char *buf, int size) 20 | { 21 | int i; 22 | 23 | for (i = 0; i < size; i++) { 24 | buf[i] = i; 25 | } 26 | } 27 | 28 | static void 29 | test_memory() 30 | { 31 | unsigned char *p1; 32 | p1 = MEM_malloc(10); 33 | dump_buffer(p1, 10); 34 | fill_buffer(p1, 10); 35 | dump_buffer(p1, 10); 36 | MEM_dump_blocks(stdout); 37 | } 38 | 39 | struct Header { 40 | int size; 41 | char c; 42 | char c1; 43 | }; 44 | 45 | union Align { 46 | double d_dummy; 47 | long l_dummy; 48 | void *p_dummy; 49 | }; 50 | 51 | typedef union { 52 | struct Header header; 53 | union Align align; 54 | } HeaderWrapper; 55 | 56 | void 57 | test_size() 58 | { 59 | printf("size of char: %ld\n", sizeof(char)); 60 | printf("size of unsigned char: %ld\n", sizeof(unsigned char)); 61 | printf("size of int: %ld\n", sizeof(int)); 62 | printf("size of long: %ld\n", sizeof(long)); 63 | printf("size of double: %ld\n", sizeof(double)); 64 | printf("size of pointer: %ld\n", sizeof(void*)); 65 | printf("size of Align: %ld\n", sizeof(union Align)); 66 | printf("size of long long: %ld\n", sizeof(long long)); 67 | printf("size of Header: %ld\n", sizeof(struct Header)); 68 | printf("size of HeaderWrapper: %ld\n", sizeof(HeaderWrapper)); 69 | } 70 | 71 | int main(void) 72 | { 73 | /* test_memory(); */ 74 | test_size(); 75 | } 76 | 77 | 78 | -------------------------------------------------------------------------------- /memory/memory.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "memory.h" 5 | 6 | static void default_error_handler(MEM_Controller controller, 7 | char *file, int line, char* msg); 8 | 9 | static struct MEM_Controller_tag st_default_controller = { 10 | NULL, 11 | default_error_handler, 12 | MEM_FAIL_AND_EXIT 13 | }; 14 | MEM_Controller mem_default_controller = &st_default_controller; 15 | 16 | 17 | static void 18 | default_error_handler(MEM_Controller controller, 19 | char* filename, int line, char *msg) 20 | { 21 | fprintf(controller->error_fp, 22 | "MEM:%s failed in %s at %d\n", msg, filename, line); 23 | } 24 | 25 | MEM_Controller 26 | MEM_create_controller(void) 27 | { 28 | MEM_Controller p; 29 | p = (MEM_Controller)MEM_malloc_func(&st_default_controller, __FILE__, __LINE__, 30 | sizeof(struct MEM_Controller_tag)); 31 | *p = st_default_controller; 32 | 33 | return p; 34 | } 35 | 36 | /** 37 | * prepend 一个新的内存块到系统里面去 38 | */ 39 | static void 40 | chain_block(MEM_Controller controller, Header *new_header) 41 | { 42 | if (controller->block_header) { 43 | controller->block_header->s.prev = new_header; 44 | } 45 | 46 | new_header->s.prev = NULL; 47 | new_header->s.next = controller->block_header; 48 | controller->block_header = new_header; 49 | } 50 | 51 | /** 52 | * 没有太明白这个函数的作用 53 | */ 54 | static void 55 | rechain_block(MEM_Controller controller, Header *header) 56 | { 57 | if (header->s.prev) { 58 | header->s.prev->s.next = header; 59 | } else { 60 | controller->block_header = header; 61 | } 62 | 63 | if (header->s.next) { 64 | header->s.next->s.prev = header; 65 | } 66 | } 67 | 68 | /** 69 | * 把一块内存从整个链子里面干掉 70 | */ 71 | static void 72 | unchain_block(MEM_Controller controller, Header *header) 73 | { 74 | if (header->s.prev) { 75 | header->s.prev->s.next = header->s.next; 76 | } else { 77 | controller->block_header = header->s.next; 78 | } 79 | 80 | if (header->s.next) { 81 | header->s.next->s.prev = header->s.prev; 82 | } 83 | } 84 | 85 | static void 86 | error_handler(MEM_Controller controller, char *filename, int line, char*msg) 87 | { 88 | if (controller->error_fp == NULL) { 89 | controller->error_fp = stderr; 90 | } 91 | controller->error_handler(controller, filename, line, msg); 92 | 93 | if (controller->fail_mode == MEM_FAIL_AND_EXIT) { 94 | exit(1); 95 | } 96 | } 97 | 98 | /* 为什么上面这些方法是 static 的? 保证只有这个文件里面可以调用 */ 99 | 100 | /** 101 | * 这里的 header size 为什么不是 MARK_SIZE, 而要这么算出来? 102 | * 因为一个结构的结尾会有 padding 103 | */ 104 | int 105 | cal_actual_header_mark_size(Header *header) 106 | { 107 | return (char*)&header[1] - (char*)header->s.mark; 108 | } 109 | 110 | /** 111 | * 初始化一个 header 112 | */ 113 | void 114 | set_header(Header *header, int size, char *filename, int line) { 115 | header->s.size = size; 116 | header->s.filename = filename; 117 | header->s.line = line; 118 | 119 | memset(header->s.mark, MARK, cal_actual_header_mark_size(header)); 120 | } 121 | 122 | /** 123 | * 把尾子也设置成 Mark 124 | */ 125 | void 126 | set_tail(void *ptr, int alloc_size) 127 | { 128 | char *tail; 129 | tail = ((char*)ptr) + alloc_size - MARK_SIZE; 130 | memset(tail, MARK, MARK_SIZE); 131 | } 132 | 133 | void 134 | check_mark_sub(unsigned char *mark, int size) 135 | { 136 | int i; 137 | for (i = 0; i < size; i++) { 138 | if (mark[i] != MARK) { 139 | fprintf(stderr, "bad mark!\n"); 140 | abort(); 141 | } 142 | } 143 | } 144 | 145 | /** 146 | * 检查一块内存头尾的 mark 是否还完好无损,如果「有损」 147 | * 那么说明出现了内存越界访问 148 | */ 149 | void 150 | check_mark(Header *header) 151 | { 152 | unsigned char *tail; 153 | check_mark_sub(header->s.mark, cal_actual_header_mark_size(header)); 154 | tail = ((unsigned char*)header) + header->s.size + sizeof(Header); 155 | check_mark_sub(tail, MARK_SIZE); 156 | } 157 | 158 | /** 159 | * 分配一块指定大小的内存,并且注册到 Controller 里面去。 160 | * 这里的注册机制是我们后面实现 GC 的前提 161 | */ 162 | void* 163 | MEM_malloc_func(MEM_Controller controller, char *filename, int line, size_t size) 164 | { 165 | void *ptr; 166 | size_t alloc_size; 167 | 168 | /* header + realsize + tail */ 169 | alloc_size = sizeof(Header) + size + MARK_SIZE; 170 | ptr = malloc(alloc_size); 171 | if (ptr == NULL) { 172 | error_handler(controller, filename, line, "malloc"); 173 | } 174 | 175 | memset(ptr, 0xCC, alloc_size); 176 | set_header(ptr, size, filename, line); 177 | set_tail(ptr, alloc_size); 178 | chain_block(controller, (Header*)ptr); 179 | ptr = (char*)ptr + sizeof(Header); 180 | 181 | return ptr; 182 | } 183 | 184 | /** 185 | * 对已经分配的一段内存的大小进行扩充 186 | */ 187 | void* 188 | MEM_realloc_func(MEM_Controller controller, char *filename, int line, 189 | void *ptr, size_t size) 190 | { 191 | void *new_ptr; 192 | size_t alloc_size; 193 | void *real_ptr; 194 | 195 | Header old_header; 196 | int old_size; 197 | 198 | alloc_size = sizeof(Header) + size + MARK_SIZE; 199 | if (ptr != NULL) { 200 | real_ptr = (char*)ptr - sizeof(Header); 201 | check_mark((Header*)real_ptr); 202 | old_header = *((Header*)real_ptr); 203 | old_size = old_header.s.size; 204 | unchain_block(controller, real_ptr); 205 | } else { 206 | real_ptr = NULL; 207 | old_size = 0; 208 | } 209 | 210 | new_ptr = realloc(real_ptr, alloc_size); 211 | if (new_ptr == NULL) { 212 | if (ptr == NULL) { 213 | error_handler(controller, filename, line, "realloc(malloc)"); 214 | } else { 215 | error_handler(controller, filename, line, "realloc"); 216 | free(real_ptr); 217 | } 218 | } 219 | 220 | Header *new_header; 221 | new_header = (Header*)new_ptr; 222 | if (ptr) { 223 | *new_header = old_header; 224 | new_header->s.size = size; 225 | rechain_block(controller, new_header); 226 | set_tail(new_ptr, alloc_size); 227 | } else { 228 | set_header(new_ptr, size, filename, line); 229 | set_tail(new_ptr, alloc_size); 230 | chain_block(controller, new_header); 231 | } 232 | 233 | new_ptr = (char*)new_ptr + sizeof(Header); 234 | if (size > old_size) { 235 | memset((char*)new_ptr + old_size, 0xCC, size - old_size); 236 | } 237 | 238 | return new_ptr; 239 | } 240 | 241 | /** 242 | * 释放一块内存 243 | */ 244 | void 245 | MEM_free_func(MEM_Controller controller, void* ptr) 246 | { 247 | Header* header; 248 | size_t size; 249 | /* 找到内存的头 */ 250 | void *actual_ptr = (char*)ptr - sizeof(Header); 251 | /* check the mark */ 252 | check_mark((Header*)actual_ptr); 253 | 254 | header = (Header*)actual_ptr; 255 | 256 | size = header->s.size; 257 | /* 把这块内存从总的链里面除下来 */ 258 | unchain_block(controller, actual_ptr); 259 | /* 这里 memset 是为了什么? */ 260 | memset(actual_ptr, 0xCC, size + sizeof(Header)); 261 | free(actual_ptr); 262 | } 263 | 264 | /** 265 | * 设置一个内存控制器的「出错处理函数」 266 | */ 267 | void 268 | MEM_set_error_handler(MEM_Controller controller, MEM_ErrorHandler handler) 269 | { 270 | controller->error_handler = handler; 271 | } 272 | 273 | void 274 | MEM_set_fail_mode(MEM_Controller controller, MEM_FailMode mode) 275 | { 276 | controller->fail_mode = mode; 277 | } 278 | 279 | 280 | void 281 | MEM_dump_blocks_func(MEM_Controller controller, FILE *fp) 282 | { 283 | Header *pos; 284 | int counter = 0; 285 | 286 | for (pos = controller->block_header; pos; pos = pos->s.next) { 287 | check_mark(pos); 288 | fprintf(fp, "[%04d]%p ******************** \n", counter, 289 | (char*)pos + sizeof(Header)); 290 | fprintf(fp, "%s line %d size..%d\n", pos->s.filename, pos->s.line, 291 | pos->s.size); 292 | counter++; 293 | } 294 | } 295 | -------------------------------------------------------------------------------- /memory/memory.h: -------------------------------------------------------------------------------- 1 | #ifndef PRIVATE_MEM_H_INCLUDED 2 | #define PRIVATE_MEM_H_INCLUDED 3 | #include "MEM.h" 4 | 5 | typedef union Header_tag Header; 6 | 7 | #define ALIGN_SIZE (sizeof(Align)) 8 | #define revalue_up_align(val) ((val) ? (((val) - 1) / ALIGN_SIZE + 1) : 0) 9 | #define HEADER_ALIGN_SIZE (revalue_up_align(sizeof(HeaderStruct))) 10 | #define MARK (0xCD) 11 | #define MARK_SIZE (4) 12 | 13 | typedef union { 14 | long l_dummy; 15 | double d_dummy; 16 | void *p_dummy; 17 | } Align; 18 | 19 | typedef struct { 20 | /* 这块内存有多大 */ 21 | int size; 22 | /* 这块内存是哪个文件申请的? */ 23 | char* filename; 24 | /* 这块内存是在哪一行申请的? */ 25 | int line; 26 | /* 前一块内存是什么? */ 27 | Header* prev; 28 | /* 后一块内存是什么? */ 29 | Header* next; 30 | /* 内存栅栏 */ 31 | unsigned char mark[MARK_SIZE]; 32 | } HeaderStruct; 33 | 34 | 35 | 36 | union Header_tag { 37 | HeaderStruct s; 38 | Align u[HEADER_ALIGN_SIZE]; 39 | }; 40 | 41 | struct MEM_Controller_tag { 42 | /* 对应的错误文件 */ 43 | FILE *error_fp; 44 | /* 出错处理程序 */ 45 | MEM_ErrorHandler error_handler; 46 | /* 内存出错时候如何处理 */ 47 | MEM_FailMode fail_mode; 48 | /* 整个内存块的头 */ 49 | Header *block_header; 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /memory/memory_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "minunit.h" 4 | #include "memory.h" 5 | 6 | int tests_run = 0; 7 | int foo = 7; 8 | int bar = 4; 9 | 10 | static char *test_foo() { 11 | mu_assert("error, foo != 7", foo == 7); 12 | return 0; 13 | } 14 | 15 | static void 16 | dump_buffer(unsigned char *buf, int size) 17 | { 18 | int i; 19 | for (i = 0; i < size; i++) { 20 | printf("%02x ", buf[i]); 21 | if (i % 16 == 15) { 22 | printf("\n"); 23 | } 24 | } 25 | printf("\n"); 26 | } 27 | 28 | static void 29 | fill_buffer(unsigned char *buf, int size) 30 | { 31 | int i; 32 | 33 | for (i = 0; i < size; i++) { 34 | buf[i] = i; 35 | } 36 | } 37 | 38 | static char* test_memory() { 39 | unsigned char *p1; 40 | Header* rawp; 41 | 42 | p1 = MEM_malloc(10); 43 | p1 = p1 - 2; 44 | dump_buffer(p1, 10); 45 | fill_buffer(p1, 10); 46 | dump_buffer(p1, 15); 47 | rawp = (Header*)(p1 - sizeof(Header)); 48 | mu_assert("memory size is not 10!", rawp->s.size == 10); 49 | 50 | return 0; 51 | } 52 | 53 | static char * all_tests() { 54 | mu_run_test(test_foo); 55 | mu_run_test(test_memory); 56 | } 57 | 58 | 59 | int main(int argc, char **argv) { 60 | char *result = all_tests(); 61 | if (result != 0) { 62 | printf("%s\n", result); 63 | } 64 | else { 65 | printf("ALL TESTS PASSED\n"); 66 | } 67 | printf("Tests run: %d\n", tests_run); 68 | 69 | return result != 0; 70 | } 71 | 72 | 73 | -------------------------------------------------------------------------------- /memory/minunit.h: -------------------------------------------------------------------------------- 1 | #define mu_assert(message, test) do { if (!(test)) return message; } while (0) 2 | #define mu_run_test(test) do { char *message = test(); tests_run++; \ 3 | if (message) return message; } while (0) 4 | extern int tests_run; 5 | -------------------------------------------------------------------------------- /memory/storage.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "memory.h" 5 | 6 | typedef union { 7 | long l_dummy; 8 | double d_dummy; 9 | void *p_dummy; 10 | } Cell; 11 | 12 | #define CELL_SIZE (sizeof(Cell)) 13 | #define DEFAULT_PAGE_SIZE (1024) 14 | 15 | typedef struct MemoryPage_tag MemoryPage; 16 | typedef MemoryPage *MemoryPageList; 17 | 18 | /** 19 | * 内存页,每个内存页有很多 cell 20 | */ 21 | struct MemoryPage_tag { 22 | /* 这个内存页里面一共有多少个 cell? */ 23 | int cell_num; 24 | /* 有多少个 cell 被使用了 */ 25 | int use_cell_num; 26 | /* 下一个内存页的引用 */ 27 | MemoryPageList next; 28 | /* 实际的的提供给外面使用的内存块在这里 */ 29 | Cell cell[1]; 30 | }; 31 | 32 | struct MEM_Storage_tag { 33 | /* 这个 storage 的内存页的列表 */ 34 | MemoryPageList page_list; 35 | /* 当前每页 page 的大小 */ 36 | int current_page_size; 37 | }; 38 | 39 | #define larger(a, b) (((a) > (b)) ? (a) : (b)) 40 | 41 | MEM_Storage 42 | MEM_open_storage_func(MEM_Controller controller, 43 | char *filename, int line, int page_size) { 44 | MEM_Storage storage; 45 | storage = MEM_malloc_func(controller, filename, line, sizeof(struct MEM_Storage_tag)); 46 | storage->page_list = NULL; 47 | assert(page_size >= 0); 48 | 49 | if (page_size > 0) { 50 | storage->current_page_size = page_size; 51 | } else { 52 | storage->current_page_size = DEFAULT_PAGE_SIZE; 53 | } 54 | 55 | return storage; 56 | } 57 | 58 | void* 59 | MEM_storage_malloc_func(MEM_Controller controller, 60 | char* filename, int line, 61 | MEM_Storage storage, 62 | size_t size) 63 | { 64 | int cell_num; 65 | void *ptr; 66 | cell_num = (size - 1) / CELL_SIZE + 1; 67 | 68 | if (storage->page_list->use_cell_num + cell_num <= storage->page_list->cell_num) { 69 | ptr = &(storage->page_list->cell[storage->page_list->use_cell_num]); 70 | storage->page_list->use_cell_num += cell_num; 71 | } else { 72 | int alloc_cell_num; 73 | MemoryPageList new_page; 74 | 75 | alloc_cell_num = larger(storage->current_page_size, cell_num); 76 | new_page = MEM_malloc_func(controller, filename, line, 77 | (alloc_cell_num - 1) * CELL_SIZE + sizeof(struct MemoryPage_tag)); 78 | new_page->cell_num = alloc_cell_num; 79 | new_page->use_cell_num = cell_num; 80 | new_page->next = storage->page_list; 81 | storage->page_list = new_page; 82 | 83 | ptr = &(new_page->cell[0]); 84 | } 85 | 86 | return ptr; 87 | } 88 | 89 | void 90 | MEM_dispose_storage_func(MEM_Controller controller, MEM_Storage storage) 91 | { 92 | MemoryPage *temp; 93 | while (storage->page_list) { 94 | temp = storage->page_list->next; 95 | MEM_free_func(controller, storage->page_list); 96 | storage->page_list = temp; 97 | } 98 | 99 | MEM_free_func(controller, storage); 100 | } 101 | -------------------------------------------------------------------------------- /memory/testp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xumingming/crowbar/00b56227bc42f4296bccce6a110e40bd16dcd60d/memory/testp -------------------------------------------------------------------------------- /string.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "MEM.h" 4 | #include "crowbar.h" 5 | 6 | static char *st_string_literal_buffer = NULL; 7 | static int st_string_literal_buffer_size = 0; 8 | static int st_string_literal_buffer_alloc_size = 0; 9 | 10 | void 11 | crb_open_string_literal(void) 12 | { 13 | st_string_literal_buffer_size = 0; 14 | } 15 | 16 | void 17 | crb_add_string_literal(int letter) 18 | { 19 | if (st_string_literal_buffer_size == st_string_literal_buffer_alloc_size) { 20 | st_string_literal_buffer_alloc_size += STRING_ALLOC_SIZE; 21 | st_string_literal_buffer = MEM_realloc(st_string_literal_buffer, 22 | st_string_literal_buffer_alloc_size); 23 | } 24 | st_string_literal_buffer[st_string_literal_buffer_size] = letter; 25 | st_string_literal_buffer_size++; 26 | } 27 | 28 | void 29 | crb_reset_string_literal_buffer() 30 | { 31 | MEM_free(st_string_literal_buffer); 32 | st_string_literal_buffer = NULL; 33 | st_string_literal_buffer_size = 0; 34 | st_string_literal_buffer_alloc_size = 0; 35 | } 36 | 37 | char * 38 | crb_close_string_literal(void) 39 | { 40 | char *p = crb_malloc(st_string_literal_buffer_size + 1); 41 | strcpy(p, st_string_literal_buffer, st_string_literal_buffer_size); 42 | p[st_string_literal_buffer_size] = '\0'; 43 | 44 | return p; 45 | } 46 | 47 | char * 48 | crb_create_identifier(char *str) 49 | { 50 | char *new_str; 51 | new_str = crb_malloc(strlen(str) + 1); 52 | strcpy(new_str, str); 53 | 54 | return new_str; 55 | } 56 | -------------------------------------------------------------------------------- /util.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "MEM.h" 4 | #include "DBG.h" 5 | #include "crowbar.h" 6 | 7 | static CRB_Interpreter *st_current_interpreter; 8 | 9 | void * 10 | crb_malloc(size_t size) 11 | { 12 | void *p; 13 | CRB_Interpreter *inter; 14 | 15 | inter = crb_get_current_interpreter(); 16 | p = MEM_storage_malloc(inter->interpreter_storage, size); 17 | 18 | return p; 19 | } 20 | 21 | FunctionDefinition * 22 | crb_search_function(char *name) 23 | { 24 | CRB_Interpreter *iter; 25 | iter = crb_get_current_interpreter(); 26 | 27 | FunctionDefinition *pos; 28 | for (pos = iter->function_list; pos; pos = pos->next) { 29 | if (!strcmp(pos->name, name)) 30 | break; 31 | } 32 | 33 | return pos; 34 | } 35 | 36 | void * 37 | crb_execute_malloc(size_t size) 38 | { 39 | void *p; 40 | CRB_Interpreter *inter; 41 | 42 | inter = crb_get_current_interpreter(); 43 | p = MEM_storage_malloc(inter->execute_storage, size); 44 | 45 | return p; 46 | } 47 | 48 | CRB_Interpreter * 49 | crb_get_current_interpreter(void) 50 | { 51 | return st_current_interpreter; 52 | } 53 | 54 | void 55 | crb_set_current_interpreter(CRB_Interpreter *inter) 56 | { 57 | st_current_interpreter = inter; 58 | } 59 | -------------------------------------------------------------------------------- /y.output: -------------------------------------------------------------------------------- 1 | Grammar 2 | 3 | 0 $accept: translation_unit $end 4 | 5 | 1 translation_unit: definition_or_statement 6 | 2 | translation_unit definition_or_statement 7 | 8 | 3 definition_or_statement: function_definition 9 | 4 | statement 10 | 11 | 5 function_definition: FUNCTION IDENTIFIER LP parameter_list RP block 12 | 6 | FUNCTION IDENTIFIER LP RP block 13 | 14 | 7 parameter_list: IDENTIFIER 15 | 8 | argument_list COMMA expression 16 | 17 | 9 argument_list: expression 18 | 10 | argument_list COMMA expression 19 | 20 | 11 statement_list: statement 21 | 12 | statement_list statement 22 | 23 | 13 expression: logical_or_expression 24 | 14 | IDENTIFIER ASSIGN expression 25 | 26 | 15 logical_or_expression: logical_and_expression 27 | 16 | logical_or_expression LOGICAL_OR logical_and_expression 28 | 29 | 17 logical_and_expression: equality_expression 30 | 18 | logical_and_expression LOGICAL_AND equality_expression 31 | 32 | 19 equality_expression: relational_expression 33 | 20 | equality_expression EQ relational_expression 34 | 21 | equality_expression NE relational_expression 35 | 36 | 22 relational_expression: additive_expression 37 | 23 | relational_expression GT additive_expression 38 | 24 | relational_expression GE additive_expression 39 | 25 | relational_expression LT additive_expression 40 | 26 | relational_expression LE additive_expression 41 | 42 | 27 additive_expression: multiplicative_expression 43 | 28 | additive_expression ADD multiplicative_expression 44 | 29 | additive_expression SUB multiplicative_expression 45 | 46 | 30 multiplicative_expression: unary_expression 47 | 31 | multiplicative_expression MUL unary_expression 48 | 32 | multiplicative_expression DIV unary_expression 49 | 33 | multiplicative_expression MOD unary_expression 50 | 51 | 34 unary_expression: primary_expression 52 | 35 | SUB unary_expression 53 | 54 | 36 primary_expression: IDENTIFIER LP argument_list RP 55 | 37 | IDENTIFIER LP RP 56 | 38 | LP expression RP 57 | 39 | IDENTIFIER 58 | 40 | INT_LITERAL 59 | 41 | DOUBLE_LITERAL 60 | 42 | STRING_LITERAL 61 | 43 | TRUE_T 62 | 44 | FALSE_T 63 | 45 | NULL_T 64 | 65 | 46 statement: expression SEMICOLON 66 | 47 | global_statement 67 | 48 | if_statement 68 | 49 | while_statement 69 | 50 | for_statement 70 | 51 | return_statement 71 | 52 | break_statement 72 | 53 | continue_statement 73 | 74 | 54 global_statement: GLOBAL_T identifier_list SEMICOLON 75 | 76 | 55 identifier_list: IDENTIFIER 77 | 56 | identifier_list COMMA IDENTIFIER 78 | 79 | 57 if_statement: IF LP expression RP block 80 | 58 | IF LP expression RP block ELSE block 81 | 59 | IF LP expression RP block elsif_list 82 | 60 | IF LP expression RP block elsif_list ELSE block 83 | 84 | 61 elsif_list: elsif 85 | 62 | elsif_list elsif 86 | 87 | 63 elsif: ELSIF LP expression RP block 88 | 89 | 64 while_statement: WHILE LP expression RP block 90 | 91 | 65 for_statement: FOR LP expression_opt SEMICOLON expression_opt SEMICOLON expression_opt RP block 92 | 93 | 66 expression_opt: /* empty */ 94 | 67 | expression 95 | 96 | 68 return_statement: RETURN_T expression_opt SEMICOLON 97 | 98 | 69 break_statement: BREAK SEMICOLON 99 | 100 | 70 continue_statement: CONTINUE SEMICOLON 101 | 102 | 71 block: LC statement_list RC 103 | 72 | LC RC 104 | 105 | 106 | Terminals, with rules where they appear 107 | 108 | $end (0) 0 109 | error (256) 110 | INT_LITERAL (258) 40 111 | DOUBLE_LITERAL (259) 41 112 | STRING_LITERAL (260) 42 113 | IDENTIFIER (261) 5 6 7 14 36 37 39 55 56 114 | FUNCTION (262) 5 6 115 | IF (263) 57 58 59 60 116 | ELSE (264) 58 60 117 | ELSIF (265) 63 118 | WHILE (266) 64 119 | FOR (267) 65 120 | RETURN_T (268) 68 121 | BREAK (269) 69 122 | CONTINUE (270) 70 123 | NULL_T (271) 45 124 | LP (272) 5 6 36 37 38 57 58 59 60 63 64 65 125 | RP (273) 5 6 36 37 38 57 58 59 60 63 64 65 126 | LC (274) 71 72 127 | RC (275) 71 72 128 | SEMICOLON (276) 46 54 65 68 69 70 129 | COMMA (277) 8 10 56 130 | ASSIGN (278) 14 131 | LOGICAL_AND (279) 18 132 | LOGICAL_OR (280) 16 133 | EQ (281) 20 134 | NE (282) 21 135 | GT (283) 23 136 | GE (284) 24 137 | LT (285) 25 138 | LE (286) 26 139 | ADD (287) 28 140 | SUB (288) 29 35 141 | MUL (289) 31 142 | DIV (290) 32 143 | MOD (291) 33 144 | TRUE_T (292) 43 145 | FALSE_T (293) 44 146 | GLOBAL_T (294) 54 147 | 148 | 149 | Nonterminals, with rules where they appear 150 | 151 | $accept (40) 152 | on left: 0 153 | translation_unit (41) 154 | on left: 1 2, on right: 0 2 155 | definition_or_statement (42) 156 | on left: 3 4, on right: 1 2 157 | function_definition (43) 158 | on left: 5 6, on right: 3 159 | parameter_list (44) 160 | on left: 7 8, on right: 5 161 | argument_list (45) 162 | on left: 9 10, on right: 8 10 36 163 | statement_list (46) 164 | on left: 11 12, on right: 12 71 165 | expression (47) 166 | on left: 13 14, on right: 8 9 10 14 38 46 57 58 59 60 63 64 67 167 | logical_or_expression (48) 168 | on left: 15 16, on right: 13 16 169 | logical_and_expression (49) 170 | on left: 17 18, on right: 15 16 18 171 | equality_expression (50) 172 | on left: 19 20 21, on right: 17 18 20 21 173 | relational_expression (51) 174 | on left: 22 23 24 25 26, on right: 19 20 21 23 24 25 26 175 | additive_expression (52) 176 | on left: 27 28 29, on right: 22 23 24 25 26 28 29 177 | multiplicative_expression (53) 178 | on left: 30 31 32 33, on right: 27 28 29 31 32 33 179 | unary_expression (54) 180 | on left: 34 35, on right: 30 31 32 33 35 181 | primary_expression (55) 182 | on left: 36 37 38 39 40 41 42 43 44 45, on right: 34 183 | statement (56) 184 | on left: 46 47 48 49 50 51 52 53, on right: 4 11 12 185 | global_statement (57) 186 | on left: 54, on right: 47 187 | identifier_list (58) 188 | on left: 55 56, on right: 54 56 189 | if_statement (59) 190 | on left: 57 58 59 60, on right: 48 191 | elsif_list (60) 192 | on left: 61 62, on right: 59 60 62 193 | elsif (61) 194 | on left: 63, on right: 61 62 195 | while_statement (62) 196 | on left: 64, on right: 49 197 | for_statement (63) 198 | on left: 65, on right: 50 199 | expression_opt (64) 200 | on left: 66 67, on right: 65 68 201 | return_statement (65) 202 | on left: 68, on right: 51 203 | break_statement (66) 204 | on left: 69, on right: 52 205 | continue_statement (67) 206 | on left: 70, on right: 53 207 | block (68) 208 | on left: 71 72, on right: 5 6 57 58 59 60 63 64 65 209 | 210 | 211 | state 0 212 | 213 | 0 $accept: . translation_unit $end 214 | 215 | INT_LITERAL shift, and go to state 1 216 | DOUBLE_LITERAL shift, and go to state 2 217 | STRING_LITERAL shift, and go to state 3 218 | IDENTIFIER shift, and go to state 4 219 | FUNCTION shift, and go to state 5 220 | IF shift, and go to state 6 221 | WHILE shift, and go to state 7 222 | FOR shift, and go to state 8 223 | RETURN_T shift, and go to state 9 224 | BREAK shift, and go to state 10 225 | CONTINUE shift, and go to state 11 226 | NULL_T shift, and go to state 12 227 | LP shift, and go to state 13 228 | SUB shift, and go to state 14 229 | TRUE_T shift, and go to state 15 230 | FALSE_T shift, and go to state 16 231 | GLOBAL_T shift, and go to state 17 232 | 233 | translation_unit go to state 18 234 | definition_or_statement go to state 19 235 | function_definition go to state 20 236 | expression go to state 21 237 | logical_or_expression go to state 22 238 | logical_and_expression go to state 23 239 | equality_expression go to state 24 240 | relational_expression go to state 25 241 | additive_expression go to state 26 242 | multiplicative_expression go to state 27 243 | unary_expression go to state 28 244 | primary_expression go to state 29 245 | statement go to state 30 246 | global_statement go to state 31 247 | if_statement go to state 32 248 | while_statement go to state 33 249 | for_statement go to state 34 250 | return_statement go to state 35 251 | break_statement go to state 36 252 | continue_statement go to state 37 253 | 254 | 255 | state 1 256 | 257 | 40 primary_expression: INT_LITERAL . 258 | 259 | $default reduce using rule 40 (primary_expression) 260 | 261 | 262 | state 2 263 | 264 | 41 primary_expression: DOUBLE_LITERAL . 265 | 266 | $default reduce using rule 41 (primary_expression) 267 | 268 | 269 | state 3 270 | 271 | 42 primary_expression: STRING_LITERAL . 272 | 273 | $default reduce using rule 42 (primary_expression) 274 | 275 | 276 | state 4 277 | 278 | 14 expression: IDENTIFIER . ASSIGN expression 279 | 36 primary_expression: IDENTIFIER . LP argument_list RP 280 | 37 | IDENTIFIER . LP RP 281 | 39 | IDENTIFIER . 282 | 283 | LP shift, and go to state 38 284 | ASSIGN shift, and go to state 39 285 | 286 | $default reduce using rule 39 (primary_expression) 287 | 288 | 289 | state 5 290 | 291 | 5 function_definition: FUNCTION . IDENTIFIER LP parameter_list RP block 292 | 6 | FUNCTION . IDENTIFIER LP RP block 293 | 294 | IDENTIFIER shift, and go to state 40 295 | 296 | 297 | state 6 298 | 299 | 57 if_statement: IF . LP expression RP block 300 | 58 | IF . LP expression RP block ELSE block 301 | 59 | IF . LP expression RP block elsif_list 302 | 60 | IF . LP expression RP block elsif_list ELSE block 303 | 304 | LP shift, and go to state 41 305 | 306 | 307 | state 7 308 | 309 | 64 while_statement: WHILE . LP expression RP block 310 | 311 | LP shift, and go to state 42 312 | 313 | 314 | state 8 315 | 316 | 65 for_statement: FOR . LP expression_opt SEMICOLON expression_opt SEMICOLON expression_opt RP block 317 | 318 | LP shift, and go to state 43 319 | 320 | 321 | state 9 322 | 323 | 68 return_statement: RETURN_T . expression_opt SEMICOLON 324 | 325 | INT_LITERAL shift, and go to state 1 326 | DOUBLE_LITERAL shift, and go to state 2 327 | STRING_LITERAL shift, and go to state 3 328 | IDENTIFIER shift, and go to state 4 329 | NULL_T shift, and go to state 12 330 | LP shift, and go to state 13 331 | SUB shift, and go to state 14 332 | TRUE_T shift, and go to state 15 333 | FALSE_T shift, and go to state 16 334 | 335 | $default reduce using rule 66 (expression_opt) 336 | 337 | expression go to state 44 338 | logical_or_expression go to state 22 339 | logical_and_expression go to state 23 340 | equality_expression go to state 24 341 | relational_expression go to state 25 342 | additive_expression go to state 26 343 | multiplicative_expression go to state 27 344 | unary_expression go to state 28 345 | primary_expression go to state 29 346 | expression_opt go to state 45 347 | 348 | 349 | state 10 350 | 351 | 69 break_statement: BREAK . SEMICOLON 352 | 353 | SEMICOLON shift, and go to state 46 354 | 355 | 356 | state 11 357 | 358 | 70 continue_statement: CONTINUE . SEMICOLON 359 | 360 | SEMICOLON shift, and go to state 47 361 | 362 | 363 | state 12 364 | 365 | 45 primary_expression: NULL_T . 366 | 367 | $default reduce using rule 45 (primary_expression) 368 | 369 | 370 | state 13 371 | 372 | 38 primary_expression: LP . expression RP 373 | 374 | INT_LITERAL shift, and go to state 1 375 | DOUBLE_LITERAL shift, and go to state 2 376 | STRING_LITERAL shift, and go to state 3 377 | IDENTIFIER shift, and go to state 4 378 | NULL_T shift, and go to state 12 379 | LP shift, and go to state 13 380 | SUB shift, and go to state 14 381 | TRUE_T shift, and go to state 15 382 | FALSE_T shift, and go to state 16 383 | 384 | expression go to state 48 385 | logical_or_expression go to state 22 386 | logical_and_expression go to state 23 387 | equality_expression go to state 24 388 | relational_expression go to state 25 389 | additive_expression go to state 26 390 | multiplicative_expression go to state 27 391 | unary_expression go to state 28 392 | primary_expression go to state 29 393 | 394 | 395 | state 14 396 | 397 | 35 unary_expression: SUB . unary_expression 398 | 399 | INT_LITERAL shift, and go to state 1 400 | DOUBLE_LITERAL shift, and go to state 2 401 | STRING_LITERAL shift, and go to state 3 402 | IDENTIFIER shift, and go to state 49 403 | NULL_T shift, and go to state 12 404 | LP shift, and go to state 13 405 | SUB shift, and go to state 14 406 | TRUE_T shift, and go to state 15 407 | FALSE_T shift, and go to state 16 408 | 409 | unary_expression go to state 50 410 | primary_expression go to state 29 411 | 412 | 413 | state 15 414 | 415 | 43 primary_expression: TRUE_T . 416 | 417 | $default reduce using rule 43 (primary_expression) 418 | 419 | 420 | state 16 421 | 422 | 44 primary_expression: FALSE_T . 423 | 424 | $default reduce using rule 44 (primary_expression) 425 | 426 | 427 | state 17 428 | 429 | 54 global_statement: GLOBAL_T . identifier_list SEMICOLON 430 | 431 | IDENTIFIER shift, and go to state 51 432 | 433 | identifier_list go to state 52 434 | 435 | 436 | state 18 437 | 438 | 0 $accept: translation_unit . $end 439 | 2 translation_unit: translation_unit . definition_or_statement 440 | 441 | $end shift, and go to state 53 442 | INT_LITERAL shift, and go to state 1 443 | DOUBLE_LITERAL shift, and go to state 2 444 | STRING_LITERAL shift, and go to state 3 445 | IDENTIFIER shift, and go to state 4 446 | FUNCTION shift, and go to state 5 447 | IF shift, and go to state 6 448 | WHILE shift, and go to state 7 449 | FOR shift, and go to state 8 450 | RETURN_T shift, and go to state 9 451 | BREAK shift, and go to state 10 452 | CONTINUE shift, and go to state 11 453 | NULL_T shift, and go to state 12 454 | LP shift, and go to state 13 455 | SUB shift, and go to state 14 456 | TRUE_T shift, and go to state 15 457 | FALSE_T shift, and go to state 16 458 | GLOBAL_T shift, and go to state 17 459 | 460 | definition_or_statement go to state 54 461 | function_definition go to state 20 462 | expression go to state 21 463 | logical_or_expression go to state 22 464 | logical_and_expression go to state 23 465 | equality_expression go to state 24 466 | relational_expression go to state 25 467 | additive_expression go to state 26 468 | multiplicative_expression go to state 27 469 | unary_expression go to state 28 470 | primary_expression go to state 29 471 | statement go to state 30 472 | global_statement go to state 31 473 | if_statement go to state 32 474 | while_statement go to state 33 475 | for_statement go to state 34 476 | return_statement go to state 35 477 | break_statement go to state 36 478 | continue_statement go to state 37 479 | 480 | 481 | state 19 482 | 483 | 1 translation_unit: definition_or_statement . 484 | 485 | $default reduce using rule 1 (translation_unit) 486 | 487 | 488 | state 20 489 | 490 | 3 definition_or_statement: function_definition . 491 | 492 | $default reduce using rule 3 (definition_or_statement) 493 | 494 | 495 | state 21 496 | 497 | 46 statement: expression . SEMICOLON 498 | 499 | SEMICOLON shift, and go to state 55 500 | 501 | 502 | state 22 503 | 504 | 13 expression: logical_or_expression . 505 | 16 logical_or_expression: logical_or_expression . LOGICAL_OR logical_and_expression 506 | 507 | LOGICAL_OR shift, and go to state 56 508 | 509 | $default reduce using rule 13 (expression) 510 | 511 | 512 | state 23 513 | 514 | 15 logical_or_expression: logical_and_expression . 515 | 18 logical_and_expression: logical_and_expression . LOGICAL_AND equality_expression 516 | 517 | LOGICAL_AND shift, and go to state 57 518 | 519 | $default reduce using rule 15 (logical_or_expression) 520 | 521 | 522 | state 24 523 | 524 | 17 logical_and_expression: equality_expression . 525 | 20 equality_expression: equality_expression . EQ relational_expression 526 | 21 | equality_expression . NE relational_expression 527 | 528 | EQ shift, and go to state 58 529 | NE shift, and go to state 59 530 | 531 | $default reduce using rule 17 (logical_and_expression) 532 | 533 | 534 | state 25 535 | 536 | 19 equality_expression: relational_expression . 537 | 23 relational_expression: relational_expression . GT additive_expression 538 | 24 | relational_expression . GE additive_expression 539 | 25 | relational_expression . LT additive_expression 540 | 26 | relational_expression . LE additive_expression 541 | 542 | GT shift, and go to state 60 543 | GE shift, and go to state 61 544 | LT shift, and go to state 62 545 | LE shift, and go to state 63 546 | 547 | $default reduce using rule 19 (equality_expression) 548 | 549 | 550 | state 26 551 | 552 | 22 relational_expression: additive_expression . 553 | 28 additive_expression: additive_expression . ADD multiplicative_expression 554 | 29 | additive_expression . SUB multiplicative_expression 555 | 556 | ADD shift, and go to state 64 557 | SUB shift, and go to state 65 558 | 559 | $default reduce using rule 22 (relational_expression) 560 | 561 | 562 | state 27 563 | 564 | 27 additive_expression: multiplicative_expression . 565 | 31 multiplicative_expression: multiplicative_expression . MUL unary_expression 566 | 32 | multiplicative_expression . DIV unary_expression 567 | 33 | multiplicative_expression . MOD unary_expression 568 | 569 | MUL shift, and go to state 66 570 | DIV shift, and go to state 67 571 | MOD shift, and go to state 68 572 | 573 | $default reduce using rule 27 (additive_expression) 574 | 575 | 576 | state 28 577 | 578 | 30 multiplicative_expression: unary_expression . 579 | 580 | $default reduce using rule 30 (multiplicative_expression) 581 | 582 | 583 | state 29 584 | 585 | 34 unary_expression: primary_expression . 586 | 587 | $default reduce using rule 34 (unary_expression) 588 | 589 | 590 | state 30 591 | 592 | 4 definition_or_statement: statement . 593 | 594 | $default reduce using rule 4 (definition_or_statement) 595 | 596 | 597 | state 31 598 | 599 | 47 statement: global_statement . 600 | 601 | $default reduce using rule 47 (statement) 602 | 603 | 604 | state 32 605 | 606 | 48 statement: if_statement . 607 | 608 | $default reduce using rule 48 (statement) 609 | 610 | 611 | state 33 612 | 613 | 49 statement: while_statement . 614 | 615 | $default reduce using rule 49 (statement) 616 | 617 | 618 | state 34 619 | 620 | 50 statement: for_statement . 621 | 622 | $default reduce using rule 50 (statement) 623 | 624 | 625 | state 35 626 | 627 | 51 statement: return_statement . 628 | 629 | $default reduce using rule 51 (statement) 630 | 631 | 632 | state 36 633 | 634 | 52 statement: break_statement . 635 | 636 | $default reduce using rule 52 (statement) 637 | 638 | 639 | state 37 640 | 641 | 53 statement: continue_statement . 642 | 643 | $default reduce using rule 53 (statement) 644 | 645 | 646 | state 38 647 | 648 | 36 primary_expression: IDENTIFIER LP . argument_list RP 649 | 37 | IDENTIFIER LP . RP 650 | 651 | INT_LITERAL shift, and go to state 1 652 | DOUBLE_LITERAL shift, and go to state 2 653 | STRING_LITERAL shift, and go to state 3 654 | IDENTIFIER shift, and go to state 4 655 | NULL_T shift, and go to state 12 656 | LP shift, and go to state 13 657 | RP shift, and go to state 69 658 | SUB shift, and go to state 14 659 | TRUE_T shift, and go to state 15 660 | FALSE_T shift, and go to state 16 661 | 662 | argument_list go to state 70 663 | expression go to state 71 664 | logical_or_expression go to state 22 665 | logical_and_expression go to state 23 666 | equality_expression go to state 24 667 | relational_expression go to state 25 668 | additive_expression go to state 26 669 | multiplicative_expression go to state 27 670 | unary_expression go to state 28 671 | primary_expression go to state 29 672 | 673 | 674 | state 39 675 | 676 | 14 expression: IDENTIFIER ASSIGN . expression 677 | 678 | INT_LITERAL shift, and go to state 1 679 | DOUBLE_LITERAL shift, and go to state 2 680 | STRING_LITERAL shift, and go to state 3 681 | IDENTIFIER shift, and go to state 4 682 | NULL_T shift, and go to state 12 683 | LP shift, and go to state 13 684 | SUB shift, and go to state 14 685 | TRUE_T shift, and go to state 15 686 | FALSE_T shift, and go to state 16 687 | 688 | expression go to state 72 689 | logical_or_expression go to state 22 690 | logical_and_expression go to state 23 691 | equality_expression go to state 24 692 | relational_expression go to state 25 693 | additive_expression go to state 26 694 | multiplicative_expression go to state 27 695 | unary_expression go to state 28 696 | primary_expression go to state 29 697 | 698 | 699 | state 40 700 | 701 | 5 function_definition: FUNCTION IDENTIFIER . LP parameter_list RP block 702 | 6 | FUNCTION IDENTIFIER . LP RP block 703 | 704 | LP shift, and go to state 73 705 | 706 | 707 | state 41 708 | 709 | 57 if_statement: IF LP . expression RP block 710 | 58 | IF LP . expression RP block ELSE block 711 | 59 | IF LP . expression RP block elsif_list 712 | 60 | IF LP . expression RP block elsif_list ELSE block 713 | 714 | INT_LITERAL shift, and go to state 1 715 | DOUBLE_LITERAL shift, and go to state 2 716 | STRING_LITERAL shift, and go to state 3 717 | IDENTIFIER shift, and go to state 4 718 | NULL_T shift, and go to state 12 719 | LP shift, and go to state 13 720 | SUB shift, and go to state 14 721 | TRUE_T shift, and go to state 15 722 | FALSE_T shift, and go to state 16 723 | 724 | expression go to state 74 725 | logical_or_expression go to state 22 726 | logical_and_expression go to state 23 727 | equality_expression go to state 24 728 | relational_expression go to state 25 729 | additive_expression go to state 26 730 | multiplicative_expression go to state 27 731 | unary_expression go to state 28 732 | primary_expression go to state 29 733 | 734 | 735 | state 42 736 | 737 | 64 while_statement: WHILE LP . expression RP block 738 | 739 | INT_LITERAL shift, and go to state 1 740 | DOUBLE_LITERAL shift, and go to state 2 741 | STRING_LITERAL shift, and go to state 3 742 | IDENTIFIER shift, and go to state 4 743 | NULL_T shift, and go to state 12 744 | LP shift, and go to state 13 745 | SUB shift, and go to state 14 746 | TRUE_T shift, and go to state 15 747 | FALSE_T shift, and go to state 16 748 | 749 | expression go to state 75 750 | logical_or_expression go to state 22 751 | logical_and_expression go to state 23 752 | equality_expression go to state 24 753 | relational_expression go to state 25 754 | additive_expression go to state 26 755 | multiplicative_expression go to state 27 756 | unary_expression go to state 28 757 | primary_expression go to state 29 758 | 759 | 760 | state 43 761 | 762 | 65 for_statement: FOR LP . expression_opt SEMICOLON expression_opt SEMICOLON expression_opt RP block 763 | 764 | INT_LITERAL shift, and go to state 1 765 | DOUBLE_LITERAL shift, and go to state 2 766 | STRING_LITERAL shift, and go to state 3 767 | IDENTIFIER shift, and go to state 4 768 | NULL_T shift, and go to state 12 769 | LP shift, and go to state 13 770 | SUB shift, and go to state 14 771 | TRUE_T shift, and go to state 15 772 | FALSE_T shift, and go to state 16 773 | 774 | $default reduce using rule 66 (expression_opt) 775 | 776 | expression go to state 44 777 | logical_or_expression go to state 22 778 | logical_and_expression go to state 23 779 | equality_expression go to state 24 780 | relational_expression go to state 25 781 | additive_expression go to state 26 782 | multiplicative_expression go to state 27 783 | unary_expression go to state 28 784 | primary_expression go to state 29 785 | expression_opt go to state 76 786 | 787 | 788 | state 44 789 | 790 | 67 expression_opt: expression . 791 | 792 | $default reduce using rule 67 (expression_opt) 793 | 794 | 795 | state 45 796 | 797 | 68 return_statement: RETURN_T expression_opt . SEMICOLON 798 | 799 | SEMICOLON shift, and go to state 77 800 | 801 | 802 | state 46 803 | 804 | 69 break_statement: BREAK SEMICOLON . 805 | 806 | $default reduce using rule 69 (break_statement) 807 | 808 | 809 | state 47 810 | 811 | 70 continue_statement: CONTINUE SEMICOLON . 812 | 813 | $default reduce using rule 70 (continue_statement) 814 | 815 | 816 | state 48 817 | 818 | 38 primary_expression: LP expression . RP 819 | 820 | RP shift, and go to state 78 821 | 822 | 823 | state 49 824 | 825 | 36 primary_expression: IDENTIFIER . LP argument_list RP 826 | 37 | IDENTIFIER . LP RP 827 | 39 | IDENTIFIER . 828 | 829 | LP shift, and go to state 38 830 | 831 | $default reduce using rule 39 (primary_expression) 832 | 833 | 834 | state 50 835 | 836 | 35 unary_expression: SUB unary_expression . 837 | 838 | $default reduce using rule 35 (unary_expression) 839 | 840 | 841 | state 51 842 | 843 | 55 identifier_list: IDENTIFIER . 844 | 845 | $default reduce using rule 55 (identifier_list) 846 | 847 | 848 | state 52 849 | 850 | 54 global_statement: GLOBAL_T identifier_list . SEMICOLON 851 | 56 identifier_list: identifier_list . COMMA IDENTIFIER 852 | 853 | SEMICOLON shift, and go to state 79 854 | COMMA shift, and go to state 80 855 | 856 | 857 | state 53 858 | 859 | 0 $accept: translation_unit $end . 860 | 861 | $default accept 862 | 863 | 864 | state 54 865 | 866 | 2 translation_unit: translation_unit definition_or_statement . 867 | 868 | $default reduce using rule 2 (translation_unit) 869 | 870 | 871 | state 55 872 | 873 | 46 statement: expression SEMICOLON . 874 | 875 | $default reduce using rule 46 (statement) 876 | 877 | 878 | state 56 879 | 880 | 16 logical_or_expression: logical_or_expression LOGICAL_OR . logical_and_expression 881 | 882 | INT_LITERAL shift, and go to state 1 883 | DOUBLE_LITERAL shift, and go to state 2 884 | STRING_LITERAL shift, and go to state 3 885 | IDENTIFIER shift, and go to state 49 886 | NULL_T shift, and go to state 12 887 | LP shift, and go to state 13 888 | SUB shift, and go to state 14 889 | TRUE_T shift, and go to state 15 890 | FALSE_T shift, and go to state 16 891 | 892 | logical_and_expression go to state 81 893 | equality_expression go to state 24 894 | relational_expression go to state 25 895 | additive_expression go to state 26 896 | multiplicative_expression go to state 27 897 | unary_expression go to state 28 898 | primary_expression go to state 29 899 | 900 | 901 | state 57 902 | 903 | 18 logical_and_expression: logical_and_expression LOGICAL_AND . equality_expression 904 | 905 | INT_LITERAL shift, and go to state 1 906 | DOUBLE_LITERAL shift, and go to state 2 907 | STRING_LITERAL shift, and go to state 3 908 | IDENTIFIER shift, and go to state 49 909 | NULL_T shift, and go to state 12 910 | LP shift, and go to state 13 911 | SUB shift, and go to state 14 912 | TRUE_T shift, and go to state 15 913 | FALSE_T shift, and go to state 16 914 | 915 | equality_expression go to state 82 916 | relational_expression go to state 25 917 | additive_expression go to state 26 918 | multiplicative_expression go to state 27 919 | unary_expression go to state 28 920 | primary_expression go to state 29 921 | 922 | 923 | state 58 924 | 925 | 20 equality_expression: equality_expression EQ . relational_expression 926 | 927 | INT_LITERAL shift, and go to state 1 928 | DOUBLE_LITERAL shift, and go to state 2 929 | STRING_LITERAL shift, and go to state 3 930 | IDENTIFIER shift, and go to state 49 931 | NULL_T shift, and go to state 12 932 | LP shift, and go to state 13 933 | SUB shift, and go to state 14 934 | TRUE_T shift, and go to state 15 935 | FALSE_T shift, and go to state 16 936 | 937 | relational_expression go to state 83 938 | additive_expression go to state 26 939 | multiplicative_expression go to state 27 940 | unary_expression go to state 28 941 | primary_expression go to state 29 942 | 943 | 944 | state 59 945 | 946 | 21 equality_expression: equality_expression NE . relational_expression 947 | 948 | INT_LITERAL shift, and go to state 1 949 | DOUBLE_LITERAL shift, and go to state 2 950 | STRING_LITERAL shift, and go to state 3 951 | IDENTIFIER shift, and go to state 49 952 | NULL_T shift, and go to state 12 953 | LP shift, and go to state 13 954 | SUB shift, and go to state 14 955 | TRUE_T shift, and go to state 15 956 | FALSE_T shift, and go to state 16 957 | 958 | relational_expression go to state 84 959 | additive_expression go to state 26 960 | multiplicative_expression go to state 27 961 | unary_expression go to state 28 962 | primary_expression go to state 29 963 | 964 | 965 | state 60 966 | 967 | 23 relational_expression: relational_expression GT . additive_expression 968 | 969 | INT_LITERAL shift, and go to state 1 970 | DOUBLE_LITERAL shift, and go to state 2 971 | STRING_LITERAL shift, and go to state 3 972 | IDENTIFIER shift, and go to state 49 973 | NULL_T shift, and go to state 12 974 | LP shift, and go to state 13 975 | SUB shift, and go to state 14 976 | TRUE_T shift, and go to state 15 977 | FALSE_T shift, and go to state 16 978 | 979 | additive_expression go to state 85 980 | multiplicative_expression go to state 27 981 | unary_expression go to state 28 982 | primary_expression go to state 29 983 | 984 | 985 | state 61 986 | 987 | 24 relational_expression: relational_expression GE . additive_expression 988 | 989 | INT_LITERAL shift, and go to state 1 990 | DOUBLE_LITERAL shift, and go to state 2 991 | STRING_LITERAL shift, and go to state 3 992 | IDENTIFIER shift, and go to state 49 993 | NULL_T shift, and go to state 12 994 | LP shift, and go to state 13 995 | SUB shift, and go to state 14 996 | TRUE_T shift, and go to state 15 997 | FALSE_T shift, and go to state 16 998 | 999 | additive_expression go to state 86 1000 | multiplicative_expression go to state 27 1001 | unary_expression go to state 28 1002 | primary_expression go to state 29 1003 | 1004 | 1005 | state 62 1006 | 1007 | 25 relational_expression: relational_expression LT . additive_expression 1008 | 1009 | INT_LITERAL shift, and go to state 1 1010 | DOUBLE_LITERAL shift, and go to state 2 1011 | STRING_LITERAL shift, and go to state 3 1012 | IDENTIFIER shift, and go to state 49 1013 | NULL_T shift, and go to state 12 1014 | LP shift, and go to state 13 1015 | SUB shift, and go to state 14 1016 | TRUE_T shift, and go to state 15 1017 | FALSE_T shift, and go to state 16 1018 | 1019 | additive_expression go to state 87 1020 | multiplicative_expression go to state 27 1021 | unary_expression go to state 28 1022 | primary_expression go to state 29 1023 | 1024 | 1025 | state 63 1026 | 1027 | 26 relational_expression: relational_expression LE . additive_expression 1028 | 1029 | INT_LITERAL shift, and go to state 1 1030 | DOUBLE_LITERAL shift, and go to state 2 1031 | STRING_LITERAL shift, and go to state 3 1032 | IDENTIFIER shift, and go to state 49 1033 | NULL_T shift, and go to state 12 1034 | LP shift, and go to state 13 1035 | SUB shift, and go to state 14 1036 | TRUE_T shift, and go to state 15 1037 | FALSE_T shift, and go to state 16 1038 | 1039 | additive_expression go to state 88 1040 | multiplicative_expression go to state 27 1041 | unary_expression go to state 28 1042 | primary_expression go to state 29 1043 | 1044 | 1045 | state 64 1046 | 1047 | 28 additive_expression: additive_expression ADD . multiplicative_expression 1048 | 1049 | INT_LITERAL shift, and go to state 1 1050 | DOUBLE_LITERAL shift, and go to state 2 1051 | STRING_LITERAL shift, and go to state 3 1052 | IDENTIFIER shift, and go to state 49 1053 | NULL_T shift, and go to state 12 1054 | LP shift, and go to state 13 1055 | SUB shift, and go to state 14 1056 | TRUE_T shift, and go to state 15 1057 | FALSE_T shift, and go to state 16 1058 | 1059 | multiplicative_expression go to state 89 1060 | unary_expression go to state 28 1061 | primary_expression go to state 29 1062 | 1063 | 1064 | state 65 1065 | 1066 | 29 additive_expression: additive_expression SUB . multiplicative_expression 1067 | 1068 | INT_LITERAL shift, and go to state 1 1069 | DOUBLE_LITERAL shift, and go to state 2 1070 | STRING_LITERAL shift, and go to state 3 1071 | IDENTIFIER shift, and go to state 49 1072 | NULL_T shift, and go to state 12 1073 | LP shift, and go to state 13 1074 | SUB shift, and go to state 14 1075 | TRUE_T shift, and go to state 15 1076 | FALSE_T shift, and go to state 16 1077 | 1078 | multiplicative_expression go to state 90 1079 | unary_expression go to state 28 1080 | primary_expression go to state 29 1081 | 1082 | 1083 | state 66 1084 | 1085 | 31 multiplicative_expression: multiplicative_expression MUL . unary_expression 1086 | 1087 | INT_LITERAL shift, and go to state 1 1088 | DOUBLE_LITERAL shift, and go to state 2 1089 | STRING_LITERAL shift, and go to state 3 1090 | IDENTIFIER shift, and go to state 49 1091 | NULL_T shift, and go to state 12 1092 | LP shift, and go to state 13 1093 | SUB shift, and go to state 14 1094 | TRUE_T shift, and go to state 15 1095 | FALSE_T shift, and go to state 16 1096 | 1097 | unary_expression go to state 91 1098 | primary_expression go to state 29 1099 | 1100 | 1101 | state 67 1102 | 1103 | 32 multiplicative_expression: multiplicative_expression DIV . unary_expression 1104 | 1105 | INT_LITERAL shift, and go to state 1 1106 | DOUBLE_LITERAL shift, and go to state 2 1107 | STRING_LITERAL shift, and go to state 3 1108 | IDENTIFIER shift, and go to state 49 1109 | NULL_T shift, and go to state 12 1110 | LP shift, and go to state 13 1111 | SUB shift, and go to state 14 1112 | TRUE_T shift, and go to state 15 1113 | FALSE_T shift, and go to state 16 1114 | 1115 | unary_expression go to state 92 1116 | primary_expression go to state 29 1117 | 1118 | 1119 | state 68 1120 | 1121 | 33 multiplicative_expression: multiplicative_expression MOD . unary_expression 1122 | 1123 | INT_LITERAL shift, and go to state 1 1124 | DOUBLE_LITERAL shift, and go to state 2 1125 | STRING_LITERAL shift, and go to state 3 1126 | IDENTIFIER shift, and go to state 49 1127 | NULL_T shift, and go to state 12 1128 | LP shift, and go to state 13 1129 | SUB shift, and go to state 14 1130 | TRUE_T shift, and go to state 15 1131 | FALSE_T shift, and go to state 16 1132 | 1133 | unary_expression go to state 93 1134 | primary_expression go to state 29 1135 | 1136 | 1137 | state 69 1138 | 1139 | 37 primary_expression: IDENTIFIER LP RP . 1140 | 1141 | $default reduce using rule 37 (primary_expression) 1142 | 1143 | 1144 | state 70 1145 | 1146 | 10 argument_list: argument_list . COMMA expression 1147 | 36 primary_expression: IDENTIFIER LP argument_list . RP 1148 | 1149 | RP shift, and go to state 94 1150 | COMMA shift, and go to state 95 1151 | 1152 | 1153 | state 71 1154 | 1155 | 9 argument_list: expression . 1156 | 1157 | $default reduce using rule 9 (argument_list) 1158 | 1159 | 1160 | state 72 1161 | 1162 | 14 expression: IDENTIFIER ASSIGN expression . 1163 | 1164 | $default reduce using rule 14 (expression) 1165 | 1166 | 1167 | state 73 1168 | 1169 | 5 function_definition: FUNCTION IDENTIFIER LP . parameter_list RP block 1170 | 6 | FUNCTION IDENTIFIER LP . RP block 1171 | 1172 | INT_LITERAL shift, and go to state 1 1173 | DOUBLE_LITERAL shift, and go to state 2 1174 | STRING_LITERAL shift, and go to state 3 1175 | IDENTIFIER shift, and go to state 96 1176 | NULL_T shift, and go to state 12 1177 | LP shift, and go to state 13 1178 | RP shift, and go to state 97 1179 | SUB shift, and go to state 14 1180 | TRUE_T shift, and go to state 15 1181 | FALSE_T shift, and go to state 16 1182 | 1183 | parameter_list go to state 98 1184 | argument_list go to state 99 1185 | expression go to state 71 1186 | logical_or_expression go to state 22 1187 | logical_and_expression go to state 23 1188 | equality_expression go to state 24 1189 | relational_expression go to state 25 1190 | additive_expression go to state 26 1191 | multiplicative_expression go to state 27 1192 | unary_expression go to state 28 1193 | primary_expression go to state 29 1194 | 1195 | 1196 | state 74 1197 | 1198 | 57 if_statement: IF LP expression . RP block 1199 | 58 | IF LP expression . RP block ELSE block 1200 | 59 | IF LP expression . RP block elsif_list 1201 | 60 | IF LP expression . RP block elsif_list ELSE block 1202 | 1203 | RP shift, and go to state 100 1204 | 1205 | 1206 | state 75 1207 | 1208 | 64 while_statement: WHILE LP expression . RP block 1209 | 1210 | RP shift, and go to state 101 1211 | 1212 | 1213 | state 76 1214 | 1215 | 65 for_statement: FOR LP expression_opt . SEMICOLON expression_opt SEMICOLON expression_opt RP block 1216 | 1217 | SEMICOLON shift, and go to state 102 1218 | 1219 | 1220 | state 77 1221 | 1222 | 68 return_statement: RETURN_T expression_opt SEMICOLON . 1223 | 1224 | $default reduce using rule 68 (return_statement) 1225 | 1226 | 1227 | state 78 1228 | 1229 | 38 primary_expression: LP expression RP . 1230 | 1231 | $default reduce using rule 38 (primary_expression) 1232 | 1233 | 1234 | state 79 1235 | 1236 | 54 global_statement: GLOBAL_T identifier_list SEMICOLON . 1237 | 1238 | $default reduce using rule 54 (global_statement) 1239 | 1240 | 1241 | state 80 1242 | 1243 | 56 identifier_list: identifier_list COMMA . IDENTIFIER 1244 | 1245 | IDENTIFIER shift, and go to state 103 1246 | 1247 | 1248 | state 81 1249 | 1250 | 16 logical_or_expression: logical_or_expression LOGICAL_OR logical_and_expression . 1251 | 18 logical_and_expression: logical_and_expression . LOGICAL_AND equality_expression 1252 | 1253 | LOGICAL_AND shift, and go to state 57 1254 | 1255 | $default reduce using rule 16 (logical_or_expression) 1256 | 1257 | 1258 | state 82 1259 | 1260 | 18 logical_and_expression: logical_and_expression LOGICAL_AND equality_expression . 1261 | 20 equality_expression: equality_expression . EQ relational_expression 1262 | 21 | equality_expression . NE relational_expression 1263 | 1264 | EQ shift, and go to state 58 1265 | NE shift, and go to state 59 1266 | 1267 | $default reduce using rule 18 (logical_and_expression) 1268 | 1269 | 1270 | state 83 1271 | 1272 | 20 equality_expression: equality_expression EQ relational_expression . 1273 | 23 relational_expression: relational_expression . GT additive_expression 1274 | 24 | relational_expression . GE additive_expression 1275 | 25 | relational_expression . LT additive_expression 1276 | 26 | relational_expression . LE additive_expression 1277 | 1278 | GT shift, and go to state 60 1279 | GE shift, and go to state 61 1280 | LT shift, and go to state 62 1281 | LE shift, and go to state 63 1282 | 1283 | $default reduce using rule 20 (equality_expression) 1284 | 1285 | 1286 | state 84 1287 | 1288 | 21 equality_expression: equality_expression NE relational_expression . 1289 | 23 relational_expression: relational_expression . GT additive_expression 1290 | 24 | relational_expression . GE additive_expression 1291 | 25 | relational_expression . LT additive_expression 1292 | 26 | relational_expression . LE additive_expression 1293 | 1294 | GT shift, and go to state 60 1295 | GE shift, and go to state 61 1296 | LT shift, and go to state 62 1297 | LE shift, and go to state 63 1298 | 1299 | $default reduce using rule 21 (equality_expression) 1300 | 1301 | 1302 | state 85 1303 | 1304 | 23 relational_expression: relational_expression GT additive_expression . 1305 | 28 additive_expression: additive_expression . ADD multiplicative_expression 1306 | 29 | additive_expression . SUB multiplicative_expression 1307 | 1308 | ADD shift, and go to state 64 1309 | SUB shift, and go to state 65 1310 | 1311 | $default reduce using rule 23 (relational_expression) 1312 | 1313 | 1314 | state 86 1315 | 1316 | 24 relational_expression: relational_expression GE additive_expression . 1317 | 28 additive_expression: additive_expression . ADD multiplicative_expression 1318 | 29 | additive_expression . SUB multiplicative_expression 1319 | 1320 | ADD shift, and go to state 64 1321 | SUB shift, and go to state 65 1322 | 1323 | $default reduce using rule 24 (relational_expression) 1324 | 1325 | 1326 | state 87 1327 | 1328 | 25 relational_expression: relational_expression LT additive_expression . 1329 | 28 additive_expression: additive_expression . ADD multiplicative_expression 1330 | 29 | additive_expression . SUB multiplicative_expression 1331 | 1332 | ADD shift, and go to state 64 1333 | SUB shift, and go to state 65 1334 | 1335 | $default reduce using rule 25 (relational_expression) 1336 | 1337 | 1338 | state 88 1339 | 1340 | 26 relational_expression: relational_expression LE additive_expression . 1341 | 28 additive_expression: additive_expression . ADD multiplicative_expression 1342 | 29 | additive_expression . SUB multiplicative_expression 1343 | 1344 | ADD shift, and go to state 64 1345 | SUB shift, and go to state 65 1346 | 1347 | $default reduce using rule 26 (relational_expression) 1348 | 1349 | 1350 | state 89 1351 | 1352 | 28 additive_expression: additive_expression ADD multiplicative_expression . 1353 | 31 multiplicative_expression: multiplicative_expression . MUL unary_expression 1354 | 32 | multiplicative_expression . DIV unary_expression 1355 | 33 | multiplicative_expression . MOD unary_expression 1356 | 1357 | MUL shift, and go to state 66 1358 | DIV shift, and go to state 67 1359 | MOD shift, and go to state 68 1360 | 1361 | $default reduce using rule 28 (additive_expression) 1362 | 1363 | 1364 | state 90 1365 | 1366 | 29 additive_expression: additive_expression SUB multiplicative_expression . 1367 | 31 multiplicative_expression: multiplicative_expression . MUL unary_expression 1368 | 32 | multiplicative_expression . DIV unary_expression 1369 | 33 | multiplicative_expression . MOD unary_expression 1370 | 1371 | MUL shift, and go to state 66 1372 | DIV shift, and go to state 67 1373 | MOD shift, and go to state 68 1374 | 1375 | $default reduce using rule 29 (additive_expression) 1376 | 1377 | 1378 | state 91 1379 | 1380 | 31 multiplicative_expression: multiplicative_expression MUL unary_expression . 1381 | 1382 | $default reduce using rule 31 (multiplicative_expression) 1383 | 1384 | 1385 | state 92 1386 | 1387 | 32 multiplicative_expression: multiplicative_expression DIV unary_expression . 1388 | 1389 | $default reduce using rule 32 (multiplicative_expression) 1390 | 1391 | 1392 | state 93 1393 | 1394 | 33 multiplicative_expression: multiplicative_expression MOD unary_expression . 1395 | 1396 | $default reduce using rule 33 (multiplicative_expression) 1397 | 1398 | 1399 | state 94 1400 | 1401 | 36 primary_expression: IDENTIFIER LP argument_list RP . 1402 | 1403 | $default reduce using rule 36 (primary_expression) 1404 | 1405 | 1406 | state 95 1407 | 1408 | 10 argument_list: argument_list COMMA . expression 1409 | 1410 | INT_LITERAL shift, and go to state 1 1411 | DOUBLE_LITERAL shift, and go to state 2 1412 | STRING_LITERAL shift, and go to state 3 1413 | IDENTIFIER shift, and go to state 4 1414 | NULL_T shift, and go to state 12 1415 | LP shift, and go to state 13 1416 | SUB shift, and go to state 14 1417 | TRUE_T shift, and go to state 15 1418 | FALSE_T shift, and go to state 16 1419 | 1420 | expression go to state 104 1421 | logical_or_expression go to state 22 1422 | logical_and_expression go to state 23 1423 | equality_expression go to state 24 1424 | relational_expression go to state 25 1425 | additive_expression go to state 26 1426 | multiplicative_expression go to state 27 1427 | unary_expression go to state 28 1428 | primary_expression go to state 29 1429 | 1430 | 1431 | state 96 1432 | 1433 | 7 parameter_list: IDENTIFIER . 1434 | 14 expression: IDENTIFIER . ASSIGN expression 1435 | 36 primary_expression: IDENTIFIER . LP argument_list RP 1436 | 37 | IDENTIFIER . LP RP 1437 | 39 | IDENTIFIER . 1438 | 1439 | LP shift, and go to state 38 1440 | ASSIGN shift, and go to state 39 1441 | 1442 | RP reduce using rule 7 (parameter_list) 1443 | $default reduce using rule 39 (primary_expression) 1444 | 1445 | 1446 | state 97 1447 | 1448 | 6 function_definition: FUNCTION IDENTIFIER LP RP . block 1449 | 1450 | LC shift, and go to state 105 1451 | 1452 | block go to state 106 1453 | 1454 | 1455 | state 98 1456 | 1457 | 5 function_definition: FUNCTION IDENTIFIER LP parameter_list . RP block 1458 | 1459 | RP shift, and go to state 107 1460 | 1461 | 1462 | state 99 1463 | 1464 | 8 parameter_list: argument_list . COMMA expression 1465 | 10 argument_list: argument_list . COMMA expression 1466 | 1467 | COMMA shift, and go to state 108 1468 | 1469 | 1470 | state 100 1471 | 1472 | 57 if_statement: IF LP expression RP . block 1473 | 58 | IF LP expression RP . block ELSE block 1474 | 59 | IF LP expression RP . block elsif_list 1475 | 60 | IF LP expression RP . block elsif_list ELSE block 1476 | 1477 | LC shift, and go to state 105 1478 | 1479 | block go to state 109 1480 | 1481 | 1482 | state 101 1483 | 1484 | 64 while_statement: WHILE LP expression RP . block 1485 | 1486 | LC shift, and go to state 105 1487 | 1488 | block go to state 110 1489 | 1490 | 1491 | state 102 1492 | 1493 | 65 for_statement: FOR LP expression_opt SEMICOLON . expression_opt SEMICOLON expression_opt RP block 1494 | 1495 | INT_LITERAL shift, and go to state 1 1496 | DOUBLE_LITERAL shift, and go to state 2 1497 | STRING_LITERAL shift, and go to state 3 1498 | IDENTIFIER shift, and go to state 4 1499 | NULL_T shift, and go to state 12 1500 | LP shift, and go to state 13 1501 | SUB shift, and go to state 14 1502 | TRUE_T shift, and go to state 15 1503 | FALSE_T shift, and go to state 16 1504 | 1505 | $default reduce using rule 66 (expression_opt) 1506 | 1507 | expression go to state 44 1508 | logical_or_expression go to state 22 1509 | logical_and_expression go to state 23 1510 | equality_expression go to state 24 1511 | relational_expression go to state 25 1512 | additive_expression go to state 26 1513 | multiplicative_expression go to state 27 1514 | unary_expression go to state 28 1515 | primary_expression go to state 29 1516 | expression_opt go to state 111 1517 | 1518 | 1519 | state 103 1520 | 1521 | 56 identifier_list: identifier_list COMMA IDENTIFIER . 1522 | 1523 | $default reduce using rule 56 (identifier_list) 1524 | 1525 | 1526 | state 104 1527 | 1528 | 10 argument_list: argument_list COMMA expression . 1529 | 1530 | $default reduce using rule 10 (argument_list) 1531 | 1532 | 1533 | state 105 1534 | 1535 | 71 block: LC . statement_list RC 1536 | 72 | LC . RC 1537 | 1538 | INT_LITERAL shift, and go to state 1 1539 | DOUBLE_LITERAL shift, and go to state 2 1540 | STRING_LITERAL shift, and go to state 3 1541 | IDENTIFIER shift, and go to state 4 1542 | IF shift, and go to state 6 1543 | WHILE shift, and go to state 7 1544 | FOR shift, and go to state 8 1545 | RETURN_T shift, and go to state 9 1546 | BREAK shift, and go to state 10 1547 | CONTINUE shift, and go to state 11 1548 | NULL_T shift, and go to state 12 1549 | LP shift, and go to state 13 1550 | RC shift, and go to state 112 1551 | SUB shift, and go to state 14 1552 | TRUE_T shift, and go to state 15 1553 | FALSE_T shift, and go to state 16 1554 | GLOBAL_T shift, and go to state 17 1555 | 1556 | statement_list go to state 113 1557 | expression go to state 21 1558 | logical_or_expression go to state 22 1559 | logical_and_expression go to state 23 1560 | equality_expression go to state 24 1561 | relational_expression go to state 25 1562 | additive_expression go to state 26 1563 | multiplicative_expression go to state 27 1564 | unary_expression go to state 28 1565 | primary_expression go to state 29 1566 | statement go to state 114 1567 | global_statement go to state 31 1568 | if_statement go to state 32 1569 | while_statement go to state 33 1570 | for_statement go to state 34 1571 | return_statement go to state 35 1572 | break_statement go to state 36 1573 | continue_statement go to state 37 1574 | 1575 | 1576 | state 106 1577 | 1578 | 6 function_definition: FUNCTION IDENTIFIER LP RP block . 1579 | 1580 | $default reduce using rule 6 (function_definition) 1581 | 1582 | 1583 | state 107 1584 | 1585 | 5 function_definition: FUNCTION IDENTIFIER LP parameter_list RP . block 1586 | 1587 | LC shift, and go to state 105 1588 | 1589 | block go to state 115 1590 | 1591 | 1592 | state 108 1593 | 1594 | 8 parameter_list: argument_list COMMA . expression 1595 | 10 argument_list: argument_list COMMA . expression 1596 | 1597 | INT_LITERAL shift, and go to state 1 1598 | DOUBLE_LITERAL shift, and go to state 2 1599 | STRING_LITERAL shift, and go to state 3 1600 | IDENTIFIER shift, and go to state 4 1601 | NULL_T shift, and go to state 12 1602 | LP shift, and go to state 13 1603 | SUB shift, and go to state 14 1604 | TRUE_T shift, and go to state 15 1605 | FALSE_T shift, and go to state 16 1606 | 1607 | expression go to state 116 1608 | logical_or_expression go to state 22 1609 | logical_and_expression go to state 23 1610 | equality_expression go to state 24 1611 | relational_expression go to state 25 1612 | additive_expression go to state 26 1613 | multiplicative_expression go to state 27 1614 | unary_expression go to state 28 1615 | primary_expression go to state 29 1616 | 1617 | 1618 | state 109 1619 | 1620 | 57 if_statement: IF LP expression RP block . 1621 | 58 | IF LP expression RP block . ELSE block 1622 | 59 | IF LP expression RP block . elsif_list 1623 | 60 | IF LP expression RP block . elsif_list ELSE block 1624 | 1625 | ELSE shift, and go to state 117 1626 | ELSIF shift, and go to state 118 1627 | 1628 | $default reduce using rule 57 (if_statement) 1629 | 1630 | elsif_list go to state 119 1631 | elsif go to state 120 1632 | 1633 | 1634 | state 110 1635 | 1636 | 64 while_statement: WHILE LP expression RP block . 1637 | 1638 | $default reduce using rule 64 (while_statement) 1639 | 1640 | 1641 | state 111 1642 | 1643 | 65 for_statement: FOR LP expression_opt SEMICOLON expression_opt . SEMICOLON expression_opt RP block 1644 | 1645 | SEMICOLON shift, and go to state 121 1646 | 1647 | 1648 | state 112 1649 | 1650 | 72 block: LC RC . 1651 | 1652 | $default reduce using rule 72 (block) 1653 | 1654 | 1655 | state 113 1656 | 1657 | 12 statement_list: statement_list . statement 1658 | 71 block: LC statement_list . RC 1659 | 1660 | INT_LITERAL shift, and go to state 1 1661 | DOUBLE_LITERAL shift, and go to state 2 1662 | STRING_LITERAL shift, and go to state 3 1663 | IDENTIFIER shift, and go to state 4 1664 | IF shift, and go to state 6 1665 | WHILE shift, and go to state 7 1666 | FOR shift, and go to state 8 1667 | RETURN_T shift, and go to state 9 1668 | BREAK shift, and go to state 10 1669 | CONTINUE shift, and go to state 11 1670 | NULL_T shift, and go to state 12 1671 | LP shift, and go to state 13 1672 | RC shift, and go to state 122 1673 | SUB shift, and go to state 14 1674 | TRUE_T shift, and go to state 15 1675 | FALSE_T shift, and go to state 16 1676 | GLOBAL_T shift, and go to state 17 1677 | 1678 | expression go to state 21 1679 | logical_or_expression go to state 22 1680 | logical_and_expression go to state 23 1681 | equality_expression go to state 24 1682 | relational_expression go to state 25 1683 | additive_expression go to state 26 1684 | multiplicative_expression go to state 27 1685 | unary_expression go to state 28 1686 | primary_expression go to state 29 1687 | statement go to state 123 1688 | global_statement go to state 31 1689 | if_statement go to state 32 1690 | while_statement go to state 33 1691 | for_statement go to state 34 1692 | return_statement go to state 35 1693 | break_statement go to state 36 1694 | continue_statement go to state 37 1695 | 1696 | 1697 | state 114 1698 | 1699 | 11 statement_list: statement . 1700 | 1701 | $default reduce using rule 11 (statement_list) 1702 | 1703 | 1704 | state 115 1705 | 1706 | 5 function_definition: FUNCTION IDENTIFIER LP parameter_list RP block . 1707 | 1708 | $default reduce using rule 5 (function_definition) 1709 | 1710 | 1711 | state 116 1712 | 1713 | 8 parameter_list: argument_list COMMA expression . 1714 | 10 argument_list: argument_list COMMA expression . 1715 | 1716 | COMMA reduce using rule 10 (argument_list) 1717 | $default reduce using rule 8 (parameter_list) 1718 | 1719 | 1720 | state 117 1721 | 1722 | 58 if_statement: IF LP expression RP block ELSE . block 1723 | 1724 | LC shift, and go to state 105 1725 | 1726 | block go to state 124 1727 | 1728 | 1729 | state 118 1730 | 1731 | 63 elsif: ELSIF . LP expression RP block 1732 | 1733 | LP shift, and go to state 125 1734 | 1735 | 1736 | state 119 1737 | 1738 | 59 if_statement: IF LP expression RP block elsif_list . 1739 | 60 | IF LP expression RP block elsif_list . ELSE block 1740 | 62 elsif_list: elsif_list . elsif 1741 | 1742 | ELSE shift, and go to state 126 1743 | ELSIF shift, and go to state 118 1744 | 1745 | $default reduce using rule 59 (if_statement) 1746 | 1747 | elsif go to state 127 1748 | 1749 | 1750 | state 120 1751 | 1752 | 61 elsif_list: elsif . 1753 | 1754 | $default reduce using rule 61 (elsif_list) 1755 | 1756 | 1757 | state 121 1758 | 1759 | 65 for_statement: FOR LP expression_opt SEMICOLON expression_opt SEMICOLON . expression_opt RP block 1760 | 1761 | INT_LITERAL shift, and go to state 1 1762 | DOUBLE_LITERAL shift, and go to state 2 1763 | STRING_LITERAL shift, and go to state 3 1764 | IDENTIFIER shift, and go to state 4 1765 | NULL_T shift, and go to state 12 1766 | LP shift, and go to state 13 1767 | SUB shift, and go to state 14 1768 | TRUE_T shift, and go to state 15 1769 | FALSE_T shift, and go to state 16 1770 | 1771 | $default reduce using rule 66 (expression_opt) 1772 | 1773 | expression go to state 44 1774 | logical_or_expression go to state 22 1775 | logical_and_expression go to state 23 1776 | equality_expression go to state 24 1777 | relational_expression go to state 25 1778 | additive_expression go to state 26 1779 | multiplicative_expression go to state 27 1780 | unary_expression go to state 28 1781 | primary_expression go to state 29 1782 | expression_opt go to state 128 1783 | 1784 | 1785 | state 122 1786 | 1787 | 71 block: LC statement_list RC . 1788 | 1789 | $default reduce using rule 71 (block) 1790 | 1791 | 1792 | state 123 1793 | 1794 | 12 statement_list: statement_list statement . 1795 | 1796 | $default reduce using rule 12 (statement_list) 1797 | 1798 | 1799 | state 124 1800 | 1801 | 58 if_statement: IF LP expression RP block ELSE block . 1802 | 1803 | $default reduce using rule 58 (if_statement) 1804 | 1805 | 1806 | state 125 1807 | 1808 | 63 elsif: ELSIF LP . expression RP block 1809 | 1810 | INT_LITERAL shift, and go to state 1 1811 | DOUBLE_LITERAL shift, and go to state 2 1812 | STRING_LITERAL shift, and go to state 3 1813 | IDENTIFIER shift, and go to state 4 1814 | NULL_T shift, and go to state 12 1815 | LP shift, and go to state 13 1816 | SUB shift, and go to state 14 1817 | TRUE_T shift, and go to state 15 1818 | FALSE_T shift, and go to state 16 1819 | 1820 | expression go to state 129 1821 | logical_or_expression go to state 22 1822 | logical_and_expression go to state 23 1823 | equality_expression go to state 24 1824 | relational_expression go to state 25 1825 | additive_expression go to state 26 1826 | multiplicative_expression go to state 27 1827 | unary_expression go to state 28 1828 | primary_expression go to state 29 1829 | 1830 | 1831 | state 126 1832 | 1833 | 60 if_statement: IF LP expression RP block elsif_list ELSE . block 1834 | 1835 | LC shift, and go to state 105 1836 | 1837 | block go to state 130 1838 | 1839 | 1840 | state 127 1841 | 1842 | 62 elsif_list: elsif_list elsif . 1843 | 1844 | $default reduce using rule 62 (elsif_list) 1845 | 1846 | 1847 | state 128 1848 | 1849 | 65 for_statement: FOR LP expression_opt SEMICOLON expression_opt SEMICOLON expression_opt . RP block 1850 | 1851 | RP shift, and go to state 131 1852 | 1853 | 1854 | state 129 1855 | 1856 | 63 elsif: ELSIF LP expression . RP block 1857 | 1858 | RP shift, and go to state 132 1859 | 1860 | 1861 | state 130 1862 | 1863 | 60 if_statement: IF LP expression RP block elsif_list ELSE block . 1864 | 1865 | $default reduce using rule 60 (if_statement) 1866 | 1867 | 1868 | state 131 1869 | 1870 | 65 for_statement: FOR LP expression_opt SEMICOLON expression_opt SEMICOLON expression_opt RP . block 1871 | 1872 | LC shift, and go to state 105 1873 | 1874 | block go to state 133 1875 | 1876 | 1877 | state 132 1878 | 1879 | 63 elsif: ELSIF LP expression RP . block 1880 | 1881 | LC shift, and go to state 105 1882 | 1883 | block go to state 134 1884 | 1885 | 1886 | state 133 1887 | 1888 | 65 for_statement: FOR LP expression_opt SEMICOLON expression_opt SEMICOLON expression_opt RP block . 1889 | 1890 | $default reduce using rule 65 (for_statement) 1891 | 1892 | 1893 | state 134 1894 | 1895 | 63 elsif: ELSIF LP expression RP block . 1896 | 1897 | $default reduce using rule 63 (elsif) 1898 | -------------------------------------------------------------------------------- /y.tab.h: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 2.3. */ 2 | 3 | /* Skeleton interface for Bison's Yacc-like parsers in C 4 | 5 | Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 6 | Free Software Foundation, Inc. 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 2, or (at your option) 11 | any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program; if not, write to the Free Software 20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 | Boston, MA 02110-1301, USA. */ 22 | 23 | /* As a special exception, you may create a larger work that contains 24 | part or all of the Bison parser skeleton and distribute that work 25 | under terms of your choice, so long as that work isn't itself a 26 | parser generator using the skeleton or a modified version thereof 27 | as a parser skeleton. Alternatively, if you modify or redistribute 28 | the parser skeleton itself, you may (at your option) remove this 29 | special exception, which will cause the skeleton and the resulting 30 | Bison output files to be licensed under the GNU General Public 31 | License without this special exception. 32 | 33 | This special exception was added by the Free Software Foundation in 34 | version 2.2 of Bison. */ 35 | 36 | /* Tokens. */ 37 | #ifndef YYTOKENTYPE 38 | # define YYTOKENTYPE 39 | /* Put the tokens into the symbol table, so that GDB and other debuggers 40 | know about them. */ 41 | enum yytokentype { 42 | INT_LITERAL = 258, 43 | DOUBLE_LITERAL = 259, 44 | STRING_LITERAL = 260, 45 | IDENTIFIER = 261, 46 | FUNCTION = 262, 47 | IF = 263, 48 | ELSE = 264, 49 | ELSIF = 265, 50 | WHILE = 266, 51 | FOR = 267, 52 | RETURN_T = 268, 53 | BREAK = 269, 54 | CONTINUE = 270, 55 | NULL_T = 271, 56 | LP = 272, 57 | RP = 273, 58 | LC = 274, 59 | RC = 275, 60 | SEMICOLON = 276, 61 | COMMA = 277, 62 | ASSIGN = 278, 63 | LOGICAL_AND = 279, 64 | LOGICAL_OR = 280, 65 | EQ = 281, 66 | NE = 282, 67 | GT = 283, 68 | GE = 284, 69 | LT = 285, 70 | LE = 286, 71 | ADD = 287, 72 | SUB = 288, 73 | MUL = 289, 74 | DIV = 290, 75 | MOD = 291, 76 | TRUE_T = 292, 77 | FALSE_T = 293, 78 | GLOBAL_T = 294 79 | }; 80 | #endif 81 | /* Tokens. */ 82 | #define INT_LITERAL 258 83 | #define DOUBLE_LITERAL 259 84 | #define STRING_LITERAL 260 85 | #define IDENTIFIER 261 86 | #define FUNCTION 262 87 | #define IF 263 88 | #define ELSE 264 89 | #define ELSIF 265 90 | #define WHILE 266 91 | #define FOR 267 92 | #define RETURN_T 268 93 | #define BREAK 269 94 | #define CONTINUE 270 95 | #define NULL_T 271 96 | #define LP 272 97 | #define RP 273 98 | #define LC 274 99 | #define RC 275 100 | #define SEMICOLON 276 101 | #define COMMA 277 102 | #define ASSIGN 278 103 | #define LOGICAL_AND 279 104 | #define LOGICAL_OR 280 105 | #define EQ 281 106 | #define NE 282 107 | #define GT 283 108 | #define GE 284 109 | #define LT 285 110 | #define LE 286 111 | #define ADD 287 112 | #define SUB 288 113 | #define MUL 289 114 | #define DIV 290 115 | #define MOD 291 116 | #define TRUE_T 292 117 | #define FALSE_T 293 118 | #define GLOBAL_T 294 119 | 120 | 121 | 122 | 123 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 124 | typedef union YYSTYPE 125 | #line 7 "crowbar.y" 126 | { 127 | char *identifier; 128 | ParameterList *parameter_list; 129 | ArgumentList *argument_list; 130 | Expression *expression; 131 | Statement *statement; 132 | StatementList *statement_list; 133 | Block *block; 134 | Elsif *elsif; 135 | IdentifierList *identifier_list; 136 | } 137 | /* Line 1529 of yacc.c. */ 138 | #line 139 "y.tab.h" 139 | YYSTYPE; 140 | # define yystype YYSTYPE /* obsolescent; will be withdrawn */ 141 | # define YYSTYPE_IS_DECLARED 1 142 | # define YYSTYPE_IS_TRIVIAL 1 143 | #endif 144 | 145 | extern YYSTYPE yylval; 146 | 147 | --------------------------------------------------------------------------------