![](https://blog.hocmai.vn/wp-content/uploads/2017/07/hot.gif)
![](https://blog.hocmai.vn/wp-content/uploads/2017/07/hot.gif)
Đây là CODE bằng C... Các bạn có thể tham khảo.
#include<stdio.h>
#include<conio.h>
#include<dos.h>
#include<string.h>
#include<stdlib.h>
char TOKEN[128][256];
int totalToken = 0;
int isWord(char s);
int isNumber(char s);
void toToken(char str[]);
int checkCommands(char str[]);
int specialChar(char c);
int tokenIsNum(char c);
struct ID
{
char *key;
char *command;
struct AST *root;
};
struct AST
{
char *key;
struct AST *left;
struct AST *right;
};
struct AST* astree(int from, int to, AST *tree);
void treePrint(AST *root, int level);
float calculator(AST *tree);
int skipToken(int skip[], int i, int length);
void main()
{
system("cls");
struct ID *head = (struct ID*) malloc(sizeof(struct ID));
head->key = "calculator";
head->command = "(18*20-10)*200-10";
struct AST *tree = (struct AST*) malloc(sizeof(struct AST));
tree->key = "+";
head->root = tree;
if (checkCommands(head->command) != 0){
printf("Error Code");
}else{
toToken(head->command);
printf("COMMAND: %s", head->command);
printf("\nTOKEN List:");
printf("\nID: %s", head->key);
for(int i = 0; i < totalToken; i++){
if (tokenIsNum(TOKEN[0]) == 0){
printf("\nOP: %s", TOKEN);
}else{
printf("\nNum: %s", TOKEN);
}
}
astree(0, totalToken, tree);
}
printf("\n");
treePrint(tree, 0);
printf("\n=%f", calculator(tree));
getch();
}
void treePrint(AST *root, int level)
{
if (root == NULL || root->key == NULL) return;
for(int i = 0; i < level; i++){
printf(i == level - 1 ? "|-" : " ");
}
printf("%s\n", root->key);
if(root->left != NULL){
treePrint(root->left, level + 1);
}
if(root->right != NULL){
treePrint(root->right, level + 1);
}
}
float calculator(AST *root){
if (root == NULL){ return 0;}
if (strcmp(root->key, "+") == 0){
return calculator(root->left) + calculator(root->right);
}else if (strcmp(root->key, "-") == 0){
return calculator(root->left) - calculator(root->right);
}else if (strcmp(root->key, "*") == 0){
return calculator(root->left) * calculator(root->right);
}else if (strcmp(root->key, "/") == 0){
return calculator(root->left) / calculator(root->right);
}else{
return atof(root->key);
}
return atof(root->key);
}
int skipToken(int skip[], int i, int length){
for(int k = 0; k < length; k++){
if (skip[k] == i){
return 1;
}
}
return 0;
}
struct AST* astree(int from, int to, AST *tree)
{
int skip[256];
int iSkip = 0;
int hasOpen = 0;
int doneOpen = 0;
for(int i = from; i <= to; i++){
if (TOKEN[0] == 40){
hasOpen++;
doneOpen++;
}
if (hasOpen > 0){
skip[iSkip++] = i;
}
if (TOKEN[0] == 41){
hasOpen--;
}
if (doneOpen > 0 && hasOpen == 0){
break;
}
}
iSkip--;
if (to-from > 1 && (iSkip == to - from || iSkip+1 == to - from)){
return astree(from+1, to-1, tree);
}
for(i = from; i <= to; i++){
if (skipToken(skip, i, iSkip) == 0){
if(TOKEN[0] == 43){
tree->key = "+";
struct AST *left = (struct AST*) malloc(sizeof(struct AST));
tree->left = left;
struct AST *right = (struct AST*) malloc(sizeof(struct AST));
tree->right = right;
left = astree(from, i-1, left);
right = astree(i+1, to, right);
return tree;
}
}
}
for(i = from; i <= to; i++){
if (skipToken(skip, i, iSkip) == 0){
if(TOKEN[0] == 45){
tree->key = "-";
struct AST *left = (struct AST*) malloc(sizeof(struct AST));
tree->left = left;
struct AST *right = (struct AST*) malloc(sizeof(struct AST));
tree->right = right;
left = astree(from, i-1, left);
right= astree(i+1, to, right);
return tree;
}
}
}
for(i = from; i <= to; i++){
if (skipToken(skip, i, iSkip) == 0){
if(TOKEN[0] == 42){
tree->key = "*";
struct AST *left = (struct AST*) malloc(sizeof(struct AST));
tree->left = left;
struct AST *right = (struct AST*) malloc(sizeof(struct AST));
tree->right = right;
left = astree(from, i-1, left);
right= astree(i+1, to, right);
return tree;
}
}
}
for(i = from; i <= to; i++){
if (skipToken(skip, i, iSkip) == 0){
if(TOKEN[0] == 47){
tree->key = "/";
struct AST *left = (struct AST*) malloc(sizeof(struct AST));
tree->left = left;
struct AST *right = (struct AST*) malloc(sizeof(struct AST));
tree->right = right;
left = astree(from, i-1, left);
right = astree(i+1, to, right);
return tree;
}
}
}
if (TOKEN[from][0] == 40){
from++;
}
if (TOKEN[to][0] == 41){
to--;
}
char* keycode = (char *)malloc(256*sizeof(char));
int index = 0;
for(i = from; i <= to; i++){
for(int k = 0; k < (sizeof(TOKEN)/sizeof(int)); k++){
keycode[index++] = TOKEN[k];
}
}
tree->key = keycode;
return tree;
}
int tokenIsNum(char c){
if (c == 40 || c == 41 || c == 31 || c == 33 || c == 34 || c == 35 || c == 36 || c == 37 || c == 38 || c == 39 || c == 42 || c == 43 || c == 44 || c == 45 || c == 46 || c == 47){
return 0;
}
return 1;
}
int specialChar(char c)
{
if (c == 33 || c == 34 || c == 35 || c == 36 || c == 37 || c == 38 || c == 39 || c == 42 || c == 43 || c == 44 || c == 45 || c == 46 || c == 47){
return 1;
}
return 0;
}
int checkCommands(char str[]){
int open = 0;
int openInside = 0;
int insideHasCorrect = 0;
int before = -1;
int current = -1;
for(int i = 0; i < strlen(str); i++)
{
if (i > 0 && specialChar(str[i-1]) == 1)
{
before = 1;
}else{
before = -1;
}
if (before == 1 && str == 41){
return -1;
}
if (specialChar(str) == 1)
{
current = 1;
}else{
current = -1;
}
if (i > 0 && before == 1 && current == 1)
{
return -1;
}
if (openInside == 1){
if (isWord(str) == 1 || isWord(str) == 2 || isNumber(str) == 1){
insideHasCorrect = 1;
}
}
if(str == 40)
{
open++;
openInside = 1;
insideHasCorrect = 0;
}
if (str == 41)
{
open--;
if (insideHasCorrect == 0){
return -1;
}
openInside = 0;
}
if (open < 0){
return open;
}
}
return open;
}
void toToken(char str[])
{
int index = 0;
int iToken = 0;
int before = -1;
int current = -1;
for(int i = 0; i < strlen(str); i++){
if(isWord(str) == 1)
{
str += 32;
}
if (i > 0){
if (isNumber(str[i-1]) == 1){
before = 1;
}
else if(isWord(str[i-1]) == 2)
{
before = 2;
}
else
{
before = 3;
}
}
if (isNumber(str) == 1)
{
current = 1;
}
else if(isWord(str) == 2)
{
current = 2;
}
else
{
current = 3;
}
if (before != -1 && (before != current || current == 3))
{
iToken += 1;
index = 0;
}
if(isNumber(str) == 1 && (before == -1 || before == 1))
{
TOKEN[iToken][index++] = str;
}
else{
if(isWord(str) == 2 && (before == -1 || before == 2))
{
TOKEN[iToken][index++] = str;
}
else
{
TOKEN[iToken][index++] = str;
}
}
}
totalToken = iToken + 1;
}
int isWord(char s)
{
if (s >= 65 && s <= 90)
{
return 1;
}
if (s >= 97 && s <= 122)
{
return 2;
}
return 0;
}
int isNumber(char s)
{
if (s >= 48 && s <= 57){
return 1;
}
return 0;
}
#include<stdio.h>
#include<conio.h>
#include<dos.h>
#include<string.h>
#include<stdlib.h>
char TOKEN[128][256];
int totalToken = 0;
int isWord(char s);
int isNumber(char s);
void toToken(char str[]);
int checkCommands(char str[]);
int specialChar(char c);
int tokenIsNum(char c);
struct ID
{
char *key;
char *command;
struct AST *root;
};
struct AST
{
char *key;
struct AST *left;
struct AST *right;
};
struct AST* astree(int from, int to, AST *tree);
void treePrint(AST *root, int level);
float calculator(AST *tree);
int skipToken(int skip[], int i, int length);
void main()
{
system("cls");
struct ID *head = (struct ID*) malloc(sizeof(struct ID));
head->key = "calculator";
head->command = "(18*20-10)*200-10";
struct AST *tree = (struct AST*) malloc(sizeof(struct AST));
tree->key = "+";
head->root = tree;
if (checkCommands(head->command) != 0){
printf("Error Code");
}else{
toToken(head->command);
printf("COMMAND: %s", head->command);
printf("\nTOKEN List:");
printf("\nID: %s", head->key);
for(int i = 0; i < totalToken; i++){
if (tokenIsNum(TOKEN[0]) == 0){
printf("\nOP: %s", TOKEN);
}else{
printf("\nNum: %s", TOKEN);
}
}
astree(0, totalToken, tree);
}
printf("\n");
treePrint(tree, 0);
printf("\n=%f", calculator(tree));
getch();
}
void treePrint(AST *root, int level)
{
if (root == NULL || root->key == NULL) return;
for(int i = 0; i < level; i++){
printf(i == level - 1 ? "|-" : " ");
}
printf("%s\n", root->key);
if(root->left != NULL){
treePrint(root->left, level + 1);
}
if(root->right != NULL){
treePrint(root->right, level + 1);
}
}
float calculator(AST *root){
if (root == NULL){ return 0;}
if (strcmp(root->key, "+") == 0){
return calculator(root->left) + calculator(root->right);
}else if (strcmp(root->key, "-") == 0){
return calculator(root->left) - calculator(root->right);
}else if (strcmp(root->key, "*") == 0){
return calculator(root->left) * calculator(root->right);
}else if (strcmp(root->key, "/") == 0){
return calculator(root->left) / calculator(root->right);
}else{
return atof(root->key);
}
return atof(root->key);
}
int skipToken(int skip[], int i, int length){
for(int k = 0; k < length; k++){
if (skip[k] == i){
return 1;
}
}
return 0;
}
struct AST* astree(int from, int to, AST *tree)
{
int skip[256];
int iSkip = 0;
int hasOpen = 0;
int doneOpen = 0;
for(int i = from; i <= to; i++){
if (TOKEN[0] == 40){
hasOpen++;
doneOpen++;
}
if (hasOpen > 0){
skip[iSkip++] = i;
}
if (TOKEN[0] == 41){
hasOpen--;
}
if (doneOpen > 0 && hasOpen == 0){
break;
}
}
iSkip--;
if (to-from > 1 && (iSkip == to - from || iSkip+1 == to - from)){
return astree(from+1, to-1, tree);
}
for(i = from; i <= to; i++){
if (skipToken(skip, i, iSkip) == 0){
if(TOKEN[0] == 43){
tree->key = "+";
struct AST *left = (struct AST*) malloc(sizeof(struct AST));
tree->left = left;
struct AST *right = (struct AST*) malloc(sizeof(struct AST));
tree->right = right;
left = astree(from, i-1, left);
right = astree(i+1, to, right);
return tree;
}
}
}
for(i = from; i <= to; i++){
if (skipToken(skip, i, iSkip) == 0){
if(TOKEN[0] == 45){
tree->key = "-";
struct AST *left = (struct AST*) malloc(sizeof(struct AST));
tree->left = left;
struct AST *right = (struct AST*) malloc(sizeof(struct AST));
tree->right = right;
left = astree(from, i-1, left);
right= astree(i+1, to, right);
return tree;
}
}
}
for(i = from; i <= to; i++){
if (skipToken(skip, i, iSkip) == 0){
if(TOKEN[0] == 42){
tree->key = "*";
struct AST *left = (struct AST*) malloc(sizeof(struct AST));
tree->left = left;
struct AST *right = (struct AST*) malloc(sizeof(struct AST));
tree->right = right;
left = astree(from, i-1, left);
right= astree(i+1, to, right);
return tree;
}
}
}
for(i = from; i <= to; i++){
if (skipToken(skip, i, iSkip) == 0){
if(TOKEN[0] == 47){
tree->key = "/";
struct AST *left = (struct AST*) malloc(sizeof(struct AST));
tree->left = left;
struct AST *right = (struct AST*) malloc(sizeof(struct AST));
tree->right = right;
left = astree(from, i-1, left);
right = astree(i+1, to, right);
return tree;
}
}
}
if (TOKEN[from][0] == 40){
from++;
}
if (TOKEN[to][0] == 41){
to--;
}
char* keycode = (char *)malloc(256*sizeof(char));
int index = 0;
for(i = from; i <= to; i++){
for(int k = 0; k < (sizeof(TOKEN)/sizeof(int)); k++){
keycode[index++] = TOKEN[k];
}
}
tree->key = keycode;
return tree;
}
int tokenIsNum(char c){
if (c == 40 || c == 41 || c == 31 || c == 33 || c == 34 || c == 35 || c == 36 || c == 37 || c == 38 || c == 39 || c == 42 || c == 43 || c == 44 || c == 45 || c == 46 || c == 47){
return 0;
}
return 1;
}
int specialChar(char c)
{
if (c == 33 || c == 34 || c == 35 || c == 36 || c == 37 || c == 38 || c == 39 || c == 42 || c == 43 || c == 44 || c == 45 || c == 46 || c == 47){
return 1;
}
return 0;
}
int checkCommands(char str[]){
int open = 0;
int openInside = 0;
int insideHasCorrect = 0;
int before = -1;
int current = -1;
for(int i = 0; i < strlen(str); i++)
{
if (i > 0 && specialChar(str[i-1]) == 1)
{
before = 1;
}else{
before = -1;
}
if (before == 1 && str == 41){
return -1;
}
if (specialChar(str) == 1)
{
current = 1;
}else{
current = -1;
}
if (i > 0 && before == 1 && current == 1)
{
return -1;
}
if (openInside == 1){
if (isWord(str) == 1 || isWord(str) == 2 || isNumber(str) == 1){
insideHasCorrect = 1;
}
}
if(str == 40)
{
open++;
openInside = 1;
insideHasCorrect = 0;
}
if (str == 41)
{
open--;
if (insideHasCorrect == 0){
return -1;
}
openInside = 0;
}
if (open < 0){
return open;
}
}
return open;
}
void toToken(char str[])
{
int index = 0;
int iToken = 0;
int before = -1;
int current = -1;
for(int i = 0; i < strlen(str); i++){
if(isWord(str) == 1)
{
str += 32;
}
if (i > 0){
if (isNumber(str[i-1]) == 1){
before = 1;
}
else if(isWord(str[i-1]) == 2)
{
before = 2;
}
else
{
before = 3;
}
}
if (isNumber(str) == 1)
{
current = 1;
}
else if(isWord(str) == 2)
{
current = 2;
}
else
{
current = 3;
}
if (before != -1 && (before != current || current == 3))
{
iToken += 1;
index = 0;
}
if(isNumber(str) == 1 && (before == -1 || before == 1))
{
TOKEN[iToken][index++] = str;
}
else{
if(isWord(str) == 2 && (before == -1 || before == 2))
{
TOKEN[iToken][index++] = str;
}
else
{
TOKEN[iToken][index++] = str;
}
}
}
totalToken = iToken + 1;
}
int isWord(char s)
{
if (s >= 65 && s <= 90)
{
return 1;
}
if (s >= 97 && s <= 122)
{
return 2;
}
return 0;
}
int isNumber(char s)
{
if (s >= 48 && s <= 57){
return 1;
}
return 0;
}