assignment problem 3
This commit is contained in:
5
assignment1/problem3/Makefile
Normal file
5
assignment1/problem3/Makefile
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
EXEC = uncompress
|
||||||
|
SRC = $(wildcard *.c)
|
||||||
|
|
||||||
|
$(EXEC): $(SRC)
|
||||||
|
gcc -o $@ $^ -Wall
|
||||||
123
assignment1/problem3/stack.c
Normal file
123
assignment1/problem3/stack.c
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* Author: Walter
|
||||||
|
* Student ID: 1930006025
|
||||||
|
* Assignment_1_Problem_3
|
||||||
|
* Stack, with functioin automaticlly increase the size
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "stack.h"
|
||||||
|
|
||||||
|
|
||||||
|
bool CreateStack(Stack *stack, int size) {
|
||||||
|
/* check */
|
||||||
|
assert(size > 0);
|
||||||
|
|
||||||
|
/* memory allocate */
|
||||||
|
stack->data = (ASTNode **)malloc(sizeof(ASTNode *) * size);
|
||||||
|
if (stack->data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* init attribute */
|
||||||
|
stack->top = -1;
|
||||||
|
stack->size = size;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsEmpty(Stack *stack) {
|
||||||
|
/* if empty, stack->top = -1 */
|
||||||
|
return stack->top < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsFull(Stack *stack) {
|
||||||
|
/* if full, stack->top = stack->size - 1 */
|
||||||
|
return stack->top == stack->size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Top(Stack *stack, ASTNode **x) {
|
||||||
|
/* check empty */
|
||||||
|
if (IsEmpty(stack)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get top */
|
||||||
|
*x = stack->data[stack->top];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Push(Stack *stack, ASTNode *x) {
|
||||||
|
/* check, enlarge stack */
|
||||||
|
if (IsFull(stack)) {
|
||||||
|
Stack newStack;
|
||||||
|
|
||||||
|
/* create new stack, with 2 bigger size */
|
||||||
|
CreateStack(&newStack, stack->size * 2);
|
||||||
|
|
||||||
|
/* copy data */
|
||||||
|
memcpy(newStack.data, stack->data, stack->size * sizeof(ASTNode *));
|
||||||
|
newStack.top = stack->top;
|
||||||
|
|
||||||
|
/* delete old stack */
|
||||||
|
DestroyStack(stack);
|
||||||
|
|
||||||
|
/* set new stack */
|
||||||
|
*stack = newStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* push */
|
||||||
|
stack->data[++stack->top] = x;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Pop(Stack *stack, ASTNode **x) {
|
||||||
|
/* check */
|
||||||
|
if (IsEmpty(stack)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get x, and top - 1 */
|
||||||
|
*x = stack->data[stack->top--];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayStack(Stack *stack) {
|
||||||
|
ASTNode **top_p = stack->data + stack->top;
|
||||||
|
|
||||||
|
/* print the top pointer hint */
|
||||||
|
printf("top --> ");
|
||||||
|
|
||||||
|
/* loop for stack data */
|
||||||
|
for (; top_p >= stack->data; top_p--) {
|
||||||
|
|
||||||
|
/* print top --> hint */
|
||||||
|
if (top_p != stack->data + stack->top) {
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("| %p |\n", top_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* print top --> hint */
|
||||||
|
if (top_p != stack->data + stack->top) {
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("+--------------+\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyStack(Stack *stack) {
|
||||||
|
free(stack->data);
|
||||||
|
stack->data = NULL;
|
||||||
|
stack->size = 0;
|
||||||
|
stack->top = -1;
|
||||||
|
}
|
||||||
41
assignment1/problem3/stack.h
Normal file
41
assignment1/problem3/stack.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef MY_STACK_H
|
||||||
|
#define MY_STACK_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Author: Walter
|
||||||
|
* Student ID: 1930006025
|
||||||
|
* Assignment_1_Problem_3
|
||||||
|
* Stack, with functioin automaticlly increase the size
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "struct.h"
|
||||||
|
|
||||||
|
#define DEFAULT_STACK_SIZE 16
|
||||||
|
|
||||||
|
/* create an stack, size will automaticlly increase */
|
||||||
|
bool CreateStack(Stack *stack, int size);
|
||||||
|
|
||||||
|
/* check a stack whether it contains data */
|
||||||
|
bool IsEmpty(Stack *stack);
|
||||||
|
|
||||||
|
/* check full of stack */
|
||||||
|
bool IsFull(Stack *stack);
|
||||||
|
|
||||||
|
/* get the top value of a stack */
|
||||||
|
bool Top(Stack *stack, ASTNode **x);
|
||||||
|
|
||||||
|
/* add a value to stack */
|
||||||
|
bool Push(Stack *stack, ASTNode *x);
|
||||||
|
|
||||||
|
/* delete a value from stack */
|
||||||
|
bool Pop(Stack *stack, ASTNode **x);
|
||||||
|
|
||||||
|
/* print the stack */
|
||||||
|
void DisplayStack(Stack *stack);
|
||||||
|
|
||||||
|
/* delete a stack */
|
||||||
|
void DestroyStack(Stack *stack);
|
||||||
|
|
||||||
|
#endif
|
||||||
74
assignment1/problem3/struct.h
Normal file
74
assignment1/problem3/struct.h
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Author: Walter
|
||||||
|
* Student ID: 1930006025
|
||||||
|
* Assignment_1_Problem_3
|
||||||
|
* the shared data structure
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MY_STRUCT_H
|
||||||
|
#define MY_STRUCT_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Used for AST Node's string */
|
||||||
|
typedef struct ASTString_str {
|
||||||
|
char *string;
|
||||||
|
|
||||||
|
/* the start index */
|
||||||
|
size_t start;
|
||||||
|
|
||||||
|
/* the end index */
|
||||||
|
size_t end;
|
||||||
|
|
||||||
|
} ASTString;
|
||||||
|
|
||||||
|
/* AST Node structure, describe in ./README.md */
|
||||||
|
typedef struct ASTNode_str {
|
||||||
|
|
||||||
|
/* 1: string, 2: left (, 3: right ) */
|
||||||
|
char type;
|
||||||
|
|
||||||
|
/* valid when type==2 */
|
||||||
|
unsigned int repeat;
|
||||||
|
|
||||||
|
/* valid when type==1 */
|
||||||
|
ASTString string;
|
||||||
|
|
||||||
|
/* next node */
|
||||||
|
struct ASTNode_str *next;
|
||||||
|
|
||||||
|
/* child node */
|
||||||
|
struct ASTNode_str *child;
|
||||||
|
} ASTNode;
|
||||||
|
|
||||||
|
/* struct for stack */
|
||||||
|
typedef struct Stack_str {
|
||||||
|
/* the size of stack */
|
||||||
|
int size;
|
||||||
|
/* top index, empty is -1 */
|
||||||
|
int top;
|
||||||
|
/* data */
|
||||||
|
ASTNode **data;
|
||||||
|
} Stack;
|
||||||
|
|
||||||
|
/* AST Scanner struct */
|
||||||
|
typedef struct ASTScanner_str {
|
||||||
|
/* pointer to string, string will not be modified */
|
||||||
|
char *string;
|
||||||
|
|
||||||
|
size_t length;
|
||||||
|
size_t current_index;
|
||||||
|
} ASTScanner;
|
||||||
|
|
||||||
|
/* AST Tree structure */
|
||||||
|
typedef struct ASTTree_str {
|
||||||
|
ASTNode *root;
|
||||||
|
ASTNode *currNode;
|
||||||
|
Stack stack;
|
||||||
|
size_t max;
|
||||||
|
size_t count;
|
||||||
|
} ASTTree;
|
||||||
|
|
||||||
|
#endif
|
||||||
16
assignment1/problem3/test_main.c
Normal file
16
assignment1/problem3/test_main.c
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "uncompress.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Uncompress(NULL, stdout);
|
||||||
|
Uncompress("", stdout);
|
||||||
|
Uncompress("abc", stdout);
|
||||||
|
Uncompress("a1(b)c", stdout);
|
||||||
|
Uncompress("a11(c)d", stdout);
|
||||||
|
Uncompress("3(a)2(bc)", stdout);
|
||||||
|
Uncompress("3(a2(c))", stdout);
|
||||||
|
Uncompress("2(abb3(cd))ef", stdout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
329
assignment1/problem3/uncompress.c
Normal file
329
assignment1/problem3/uncompress.c
Normal file
@@ -0,0 +1,329 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "uncompress.h"
|
||||||
|
#include "stack.h"
|
||||||
|
|
||||||
|
ASTScanner *CreateASTScanner(char *string) {
|
||||||
|
/* Special case define in pdf */
|
||||||
|
if (string == NULL) {
|
||||||
|
string = "NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate scanner memory space */
|
||||||
|
ASTScanner *scanner = (ASTScanner *)malloc(sizeof(ASTScanner));
|
||||||
|
if (scanner == NULL) {
|
||||||
|
fprintf(stderr, "allocate scanner memory failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* init values */
|
||||||
|
scanner->string = string;
|
||||||
|
scanner->length = strlen(string);
|
||||||
|
scanner->current_index = 0;
|
||||||
|
|
||||||
|
return scanner;
|
||||||
|
}
|
||||||
|
|
||||||
|
char ASTScan(ASTScanner *scanner, ASTNode **ret_node) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/* return if it reached the end */
|
||||||
|
if (scanner->current_index == scanner->length) {
|
||||||
|
*ret_node = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate memory space */
|
||||||
|
ASTNode *node = (ASTNode *)calloc(1, sizeof(ASTNode));
|
||||||
|
if (node == NULL) {
|
||||||
|
fprintf(stderr, "allocate ASTNode memory failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read until end or '(' or ')',
|
||||||
|
* after the loop, i point after '(' or ')' */
|
||||||
|
i = scanner->current_index;
|
||||||
|
while (i < scanner->length) {
|
||||||
|
if (scanner->string[i]=='(' || scanner->string[i] == ')') {
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if read ( */
|
||||||
|
if (scanner->string[i-1] == '(') {
|
||||||
|
node->type = 2;
|
||||||
|
|
||||||
|
/* check is there is any number before ( */
|
||||||
|
if (i-1 == 0) {
|
||||||
|
fprintf(stderr, "Syntax error: invailed value of repeat at begining\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!IsNumber(scanner->string[i-2])) {
|
||||||
|
fprintf(stderr, "Syntax error: invailed value of repeat at index %ld\n", i-1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get number and the string before the number */
|
||||||
|
node->repeat = GetNumber(scanner->string, scanner->current_index, i-1, &node->string);
|
||||||
|
/* if the string exists */
|
||||||
|
if (node->string.string) {
|
||||||
|
/* change type to 1 */
|
||||||
|
node->type = 1;
|
||||||
|
node->repeat = 0;
|
||||||
|
i = node->string.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if read ) */
|
||||||
|
} else if (scanner->string[i-1] == ')') {
|
||||||
|
node->type = 3;
|
||||||
|
|
||||||
|
/* if there are string before ) */
|
||||||
|
if (i-1 != scanner->current_index) {
|
||||||
|
|
||||||
|
/* change type to 1 */
|
||||||
|
node->type = 1;
|
||||||
|
node->string.string = scanner->string;
|
||||||
|
node->string.start = scanner->current_index;
|
||||||
|
node->string.end = i-1;
|
||||||
|
i = i - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* until the end is a string */
|
||||||
|
} else {
|
||||||
|
node->type = 1;
|
||||||
|
node->string.string = scanner->string;
|
||||||
|
node->string.start = scanner->current_index;
|
||||||
|
node->string.end = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set current_index */
|
||||||
|
scanner->current_index = i;
|
||||||
|
|
||||||
|
/* set return node */
|
||||||
|
*ret_node = node;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int GetNumber(char *string, size_t start, size_t end, ASTString *other_string) {
|
||||||
|
unsigned int result = 0;
|
||||||
|
size_t index = end - 1;
|
||||||
|
|
||||||
|
/* convert string to integer */
|
||||||
|
for (unsigned count = 1; IsNumber(string[index]); index--, count++) {
|
||||||
|
result = result + (string[index] - '0') * Power(10, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if there is a string before the number,
|
||||||
|
* set to other_string */
|
||||||
|
if (index + 1 != start) {
|
||||||
|
other_string->string = string;
|
||||||
|
other_string->start = start;
|
||||||
|
other_string->end = index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsNumber(const char c) {
|
||||||
|
return c >= '0' && c <= '9';
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Power(int x, int y) {
|
||||||
|
unsigned int result = 1;
|
||||||
|
for (int i=1; i<y; i++) {
|
||||||
|
result = result * x;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DEBUG_NODE(ASTNode *root) {
|
||||||
|
ASTNode *currNode = root;
|
||||||
|
while (currNode) {
|
||||||
|
printf("[%p] type: %d, next: %p, child: %p, repeat: %d, string: %ld-%ld\n",
|
||||||
|
currNode,
|
||||||
|
currNode->type,
|
||||||
|
currNode->next,
|
||||||
|
currNode->child,
|
||||||
|
currNode->repeat,
|
||||||
|
currNode->string.start,
|
||||||
|
currNode->string.end);
|
||||||
|
|
||||||
|
if (currNode->type == 2) {
|
||||||
|
/* recursion to child */
|
||||||
|
DEBUG_NODE(currNode->child);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* move forward */
|
||||||
|
currNode = currNode->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyASTTree(ASTTree *tree) {
|
||||||
|
ASTNode *currNode, *delNode;
|
||||||
|
|
||||||
|
/* push root node into stack */
|
||||||
|
Push(&tree->stack, tree->root);
|
||||||
|
|
||||||
|
/* loop to destroy all node */
|
||||||
|
while (!IsEmpty(&tree->stack)) {
|
||||||
|
|
||||||
|
/* get node from stack */
|
||||||
|
Pop(&tree->stack, &currNode);
|
||||||
|
|
||||||
|
while (currNode) {
|
||||||
|
|
||||||
|
if (currNode->type == 2) {
|
||||||
|
/* store child node into stack */
|
||||||
|
Push(&tree->stack, currNode->child);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete node */
|
||||||
|
delNode = currNode;
|
||||||
|
currNode = currNode->next;
|
||||||
|
free(delNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* finally do not forget to free everything */
|
||||||
|
DestroyStack(&tree->stack);
|
||||||
|
free(tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTTree *CreateASTTree() {
|
||||||
|
/* allocate memory */
|
||||||
|
ASTTree *tree = (ASTTree *)calloc(1, sizeof(ASTTree));
|
||||||
|
if (tree == NULL) {
|
||||||
|
fprintf(stderr, "Can not allocate AST Tree memory\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create stack with tree */
|
||||||
|
CreateStack(&tree->stack, DEFAULT_STACK_SIZE);
|
||||||
|
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTCompileTree(ASTTree *tree, FILE *file) {
|
||||||
|
|
||||||
|
ASTCompileNode(tree->root, file);
|
||||||
|
|
||||||
|
/* new line at the end */
|
||||||
|
fputc('\n', file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTCompileNode(ASTNode *root, FILE *file) {
|
||||||
|
ASTNode *currNode = root;
|
||||||
|
|
||||||
|
/* loop for node and its all next node */
|
||||||
|
for (; currNode; currNode = currNode->next) {
|
||||||
|
|
||||||
|
if (currNode->type == 2) {
|
||||||
|
/* repeat to compile child node */
|
||||||
|
for (int i=0; i<currNode->repeat; i++) {
|
||||||
|
/* recursion */
|
||||||
|
ASTCompileNode(currNode->child, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (currNode->type == 1) {
|
||||||
|
/* print string */
|
||||||
|
for (size_t i=currNode->string.start; i<currNode->string.end; i++) {
|
||||||
|
fputc(currNode->string.string[i], file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char ASTScanAll(ASTTree *tree, ASTScanner *scanner) {
|
||||||
|
bool goback = false;
|
||||||
|
char err;
|
||||||
|
ASTNode *node = NULL, *last = NULL;
|
||||||
|
|
||||||
|
/* scan the first (root) node */
|
||||||
|
ASTScan(scanner, &node);
|
||||||
|
tree->root = node;
|
||||||
|
tree->max++;
|
||||||
|
last = tree->root;
|
||||||
|
|
||||||
|
/* set last node as last type 2 node */
|
||||||
|
if (node != NULL) {
|
||||||
|
if (node->type == 2) {
|
||||||
|
Push(&tree->stack, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* scan until end */
|
||||||
|
while(err = ASTScan(scanner, &node), node) {
|
||||||
|
|
||||||
|
/* raise error */
|
||||||
|
if (err != 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set goback flag, set last node as last type 2 node */
|
||||||
|
if (node->type == 3) {
|
||||||
|
goback = true;
|
||||||
|
Pop(&tree->stack, &last);
|
||||||
|
free(node);
|
||||||
|
continue;
|
||||||
|
/* uf node type is 2, record in stack */
|
||||||
|
} else if (node->type == 2) {
|
||||||
|
Push(&tree->stack, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* connect to last node */
|
||||||
|
if (last->type == 1) {
|
||||||
|
last->next = node;
|
||||||
|
} else if (last->type == 2) {
|
||||||
|
if (goback) {
|
||||||
|
last->next = node;
|
||||||
|
goback = false;
|
||||||
|
} else {
|
||||||
|
last->child = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* record last node, increase max */
|
||||||
|
last = node;
|
||||||
|
tree->max++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Uncompress(char *string, FILE *file) {
|
||||||
|
char err;
|
||||||
|
|
||||||
|
/* create scanner and AST tree */
|
||||||
|
ASTScanner *scanner = CreateASTScanner(string);
|
||||||
|
ASTTree *tree = CreateASTTree();
|
||||||
|
|
||||||
|
/* scan all token into tree */
|
||||||
|
err = ASTScanAll(tree, scanner);
|
||||||
|
if (err != 0) {
|
||||||
|
fprintf(stderr, "EXITED");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
printf("---debug---\n");
|
||||||
|
DEBUG_NODE(tree->root);
|
||||||
|
printf("---debug---\n");
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* compile */
|
||||||
|
ASTCompileTree(tree, file);
|
||||||
|
|
||||||
|
/* free memory */
|
||||||
|
DestroyASTTree(tree);
|
||||||
|
DestroyASTScanner(scanner);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyASTScanner(ASTScanner *scanner) {
|
||||||
|
free(scanner);
|
||||||
|
}
|
||||||
49
assignment1/problem3/uncompress.h
Normal file
49
assignment1/problem3/uncompress.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#ifndef UNCOMPRESS
|
||||||
|
#define UNCOMPRESS
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "struct.h"
|
||||||
|
|
||||||
|
/* return a pointer of a new scanner, string will not be copied */
|
||||||
|
ASTScanner *CreateASTScanner(char *string);
|
||||||
|
|
||||||
|
/* return a pointer of a new Tree */
|
||||||
|
ASTTree *CreateASTTree();
|
||||||
|
|
||||||
|
/* return a pointer of a token, return NULL if reached the end */
|
||||||
|
char ASTScan(ASTScanner *scanner, ASTNode **ret_node);
|
||||||
|
|
||||||
|
/* scan all token from scanner into tree */
|
||||||
|
char ASTScanAll(ASTTree *tree, ASTScanner *scanner);
|
||||||
|
|
||||||
|
/* return the number before a string with index */
|
||||||
|
unsigned int GetNumber(char *string, size_t start, size_t end, ASTString *other_string);
|
||||||
|
|
||||||
|
/* Useful function to check whether a char is a number */
|
||||||
|
bool IsNumber(const char c);
|
||||||
|
|
||||||
|
/* math calc, Power(10, 4) return 10000 */
|
||||||
|
unsigned int Power(int x, int y);
|
||||||
|
|
||||||
|
/* destroy AST scanner, memory of string will not be free */
|
||||||
|
void DestroyASTScanner(ASTScanner *scanner);
|
||||||
|
|
||||||
|
/* Destroy AST Tree */
|
||||||
|
void DestroyASTTree(ASTTree *tree);
|
||||||
|
|
||||||
|
/* Display debug information to screen from root node */
|
||||||
|
void DEBUG_NODE(ASTNode *root);
|
||||||
|
|
||||||
|
/* Compile the tree to file stream */
|
||||||
|
void ASTCompileTree(ASTTree *tree, FILE *file);
|
||||||
|
|
||||||
|
/* Compile node and its all next node to file stream */
|
||||||
|
void ASTCompileNode(ASTNode *root, FILE *file);
|
||||||
|
|
||||||
|
/* A short cut function, directly uncompress the raw string to file stream */
|
||||||
|
void Uncompress(char *string, FILE *file);
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user