-
Notifications
You must be signed in to change notification settings - Fork 0
Interactive mode for working with the parse tree #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 6 commits
531d1f9
ee27bff
0d36fbd
378356e
918278c
66ff87e
8780d7e
e1c6faa
41a7a49
2986452
42479cd
761ccf5
0215130
9e88d89
014c909
1b46e0f
fe132ff
51a7b22
d1eb0d2
30f11f0
48984d1
2216d55
4c9585b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| | ||
| Microsoft Visual Studio Solution File, Format Version 12.00 | ||
| # Visual Studio Version 16 | ||
| VisualStudioVersion = 16.0.31410.357 | ||
| MinimumVisualStudioVersion = 10.0.40219.1 | ||
| Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ParsingTree", "ParsingTree\ParsingTree.vcxproj", "{AEA90FA6-F26C-4B74-9508-AD999204C4FA}" | ||
| EndProject | ||
| Global | ||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
| Debug|x64 = Debug|x64 | ||
| Debug|x86 = Debug|x86 | ||
| Release|x64 = Release|x64 | ||
| Release|x86 = Release|x86 | ||
| EndGlobalSection | ||
| GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
| {AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Debug|x64.ActiveCfg = Debug|x64 | ||
| {AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Debug|x64.Build.0 = Debug|x64 | ||
| {AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Debug|x86.ActiveCfg = Debug|Win32 | ||
| {AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Debug|x86.Build.0 = Debug|Win32 | ||
| {AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Release|x64.ActiveCfg = Release|x64 | ||
| {AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Release|x64.Build.0 = Release|x64 | ||
| {AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Release|x86.ActiveCfg = Release|Win32 | ||
| {AEA90FA6-F26C-4B74-9508-AD999204C4FA}.Release|x86.Build.0 = Release|Win32 | ||
| EndGlobalSection | ||
| GlobalSection(SolutionProperties) = preSolution | ||
| HideSolutionNode = FALSE | ||
| EndGlobalSection | ||
| GlobalSection(ExtensibilityGlobals) = postSolution | ||
| SolutionGuid = {65329AED-E765-4723-93C5-B2671094F619} | ||
| EndGlobalSection | ||
| EndGlobal |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| #include "TestParsingTree.h" | ||
|
|
||
| int main() | ||
| { | ||
| if (!testFindAnswer() || !testBuildTree()) | ||
| { | ||
| return -1; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,282 @@ | ||||||
| #include "ParsingTree.h" | ||||||
| #include <stdlib.h> | ||||||
| #include <stdio.h> | ||||||
| #include <stdbool.h> | ||||||
|
|
||||||
| typedef struct Node | ||||||
| { | ||||||
| struct Node* leftSon; | ||||||
| struct Node* rightSon; | ||||||
| struct Node* parent; | ||||||
| char value; | ||||||
| int number; | ||||||
| char help; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
| } Node; | ||||||
|
|
||||||
| Node* createTree() | ||||||
| { | ||||||
| return NULL; | ||||||
| } | ||||||
|
|
||||||
| void deleteTreeRecursive(Node* root) | ||||||
| { | ||||||
| if (root == NULL) | ||||||
| { | ||||||
| return; | ||||||
| } | ||||||
| deleteTreeRecursive(root->leftSon); | ||||||
| deleteTreeRecursive(root->rightSon); | ||||||
| free(root); | ||||||
| } | ||||||
|
|
||||||
| void deleteTree(Node** root) | ||||||
| { | ||||||
| deleteTreeRecursive(*root); | ||||||
| *root = NULL; | ||||||
| } | ||||||
|
|
||||||
| Node* returnHead(Node* root) | ||||||
| { | ||||||
| if (root == NULL) | ||||||
| { | ||||||
| return root; | ||||||
| } | ||||||
| while (root->parent != NULL) | ||||||
| { | ||||||
| root = root->parent; | ||||||
| } | ||||||
| return root; | ||||||
| } | ||||||
|
|
||||||
| int returnAnswer(Node* root) | ||||||
| { | ||||||
| return root->number; | ||||||
| } | ||||||
|
|
||||||
| bool compare(char symbol) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тоже название не очень. compare чего с чем? Тем более тут проверяется, является ли символ оператором, так что я бы isOperator это назвал |
||||||
| { | ||||||
| return symbol == '+' || symbol == '-' | ||||||
| || symbol == '*' || symbol == '/'; | ||||||
| } | ||||||
|
|
||||||
| Node* buildTree(char* array) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||
| { | ||||||
| int counter = 0; | ||||||
| Node* tree = createTree(); | ||||||
| while (array[counter] != '\0') | ||||||
| { | ||||||
| if (array[counter] == '(' || array[counter] == ')' || array[counter] == ' ') | ||||||
| { | ||||||
| counter++; | ||||||
| continue; | ||||||
| } | ||||||
| Node* newRoot = (Node*)calloc(1, sizeof(Node)); | ||||||
| if (newRoot == NULL) | ||||||
| { | ||||||
| return NULL; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Так всё построенное до этого дерево потеряется |
||||||
| } | ||||||
| if (tree == NULL) | ||||||
| { | ||||||
| newRoot->value = array[counter]; | ||||||
| tree = newRoot; | ||||||
| newRoot->help = '!'; | ||||||
| newRoot->number = 0; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Будет ли это хорошо работать на строках вида |
||||||
| counter++; | ||||||
| continue; | ||||||
| } | ||||||
| if (compare(array[counter])) | ||||||
| { | ||||||
| if (tree->leftSon == NULL && compare(tree->value)) | ||||||
| { | ||||||
| tree->leftSon = newRoot; | ||||||
| newRoot->parent = tree; | ||||||
| newRoot->help = '!'; | ||||||
| newRoot->value = array[counter]; | ||||||
| newRoot->number = 0; | ||||||
| tree = newRoot; | ||||||
| counter++; | ||||||
| continue; | ||||||
| } | ||||||
| else if (tree->rightSon == NULL && compare(tree->value)) | ||||||
| { | ||||||
| tree->rightSon = newRoot; | ||||||
| newRoot->parent = tree; | ||||||
| newRoot->help = '!'; | ||||||
| newRoot->value = array[counter]; | ||||||
| newRoot->number = 0; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Что-то копипаст. Можно инициализацию узла вынести в отдельную функцию |
||||||
| tree = newRoot; | ||||||
| counter++; | ||||||
| continue; | ||||||
| } | ||||||
| while (tree->parent != NULL) | ||||||
| { | ||||||
| tree = tree->parent; | ||||||
| if (tree->leftSon == NULL && compare(tree->value)) | ||||||
| { | ||||||
| tree->leftSon = newRoot; | ||||||
| newRoot->parent = tree; | ||||||
| newRoot->help = '!'; | ||||||
| newRoot->value = array[counter]; | ||||||
| newRoot->number = 0; | ||||||
| counter++; | ||||||
| tree = newRoot; | ||||||
| break; | ||||||
| } | ||||||
| else if (tree->rightSon == NULL && compare(tree->value)) | ||||||
| { | ||||||
| tree->rightSon = newRoot; | ||||||
| newRoot->parent = tree; | ||||||
| newRoot->help = '!'; | ||||||
| newRoot->value = array[counter]; | ||||||
| newRoot->number = 0; | ||||||
| counter++; | ||||||
| tree = newRoot; | ||||||
| break; | ||||||
| } | ||||||
| } | ||||||
| continue; | ||||||
| } | ||||||
| if (array[counter] <= '9' && array[counter] >= '0') | ||||||
| { | ||||||
| if (compare(tree->value) && tree->leftSon == NULL) | ||||||
| { | ||||||
| tree->leftSon = newRoot; | ||||||
| newRoot->parent = tree; | ||||||
| newRoot->value = array[counter]; | ||||||
| newRoot->help = '$'; | ||||||
| newRoot->number = array[counter] - '0'; | ||||||
| counter++; | ||||||
| continue; | ||||||
| } | ||||||
| else if (tree->rightSon == NULL && compare(tree->value)) | ||||||
| { | ||||||
| tree->rightSon = newRoot; | ||||||
| newRoot->parent = tree; | ||||||
| newRoot->value = array[counter]; | ||||||
| newRoot->help = '$'; | ||||||
| newRoot->number = array[counter] - '0'; | ||||||
| counter++; | ||||||
| continue; | ||||||
| } | ||||||
| while (tree->parent != NULL) | ||||||
| { | ||||||
| tree = tree->parent; | ||||||
| if (tree->leftSon == NULL && compare(tree->value)) | ||||||
| { | ||||||
| tree->leftSon = newRoot; | ||||||
| newRoot->parent = tree; | ||||||
| newRoot->value = array[counter]; | ||||||
| newRoot->help = '$'; | ||||||
| newRoot->number = array[counter] - '0'; | ||||||
| counter++; | ||||||
| break; | ||||||
| } | ||||||
| else if (tree->rightSon == NULL && compare(tree->value)) | ||||||
| { | ||||||
| tree->rightSon = newRoot; | ||||||
| newRoot->parent = tree; | ||||||
| newRoot->value = array[counter]; | ||||||
| newRoot->help = '$'; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Это какой-то тайный шифр? |
||||||
| newRoot->number = array[counter] - '0'; | ||||||
| counter++; | ||||||
| break; | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
| return tree; | ||||||
| } | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Капец как сложно. Это рекурсивно в 20 строк пишется: if (isOperator(array[*i])
{
Node *operator = createOperator(array[*i]);
++*i;
operator->left = buildTree(array, i);
operator->right = buildTree(array, i);
return operator;
}
else
{
Node *operand = createOperand(array[*i])
++*i;
return operand;
} |
||||||
|
|
||||||
| void restoreField(Node* root) | ||||||
| { | ||||||
| if (root == NULL) | ||||||
| { | ||||||
| return; | ||||||
| } | ||||||
| restoreField(root->leftSon); | ||||||
| restoreField(root->rightSon); | ||||||
| if (compare(root->value)) | ||||||
| { | ||||||
| root->help = '!'; | ||||||
| } | ||||||
| else | ||||||
| { | ||||||
| root->help = '$'; | ||||||
| } | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тернарным оператором было бы короче |
||||||
| } | ||||||
|
|
||||||
| void findAnswer(Node* root) | ||||||
| { | ||||||
| if (root == NULL) | ||||||
| { | ||||||
| return; | ||||||
| } | ||||||
| if (root->leftSon != NULL && root->rightSon != NULL && root->rightSon->help == '$' && root->leftSon->help == '$' && root->help != '$') | ||||||
| { | ||||||
| root->help = '$'; | ||||||
| if (root->value == '+') | ||||||
| { | ||||||
| root->number = root->leftSon->number + root->rightSon->number; | ||||||
| } | ||||||
| if (root->value == '-') | ||||||
| { | ||||||
| root->number = root->leftSon->number - root->rightSon->number; | ||||||
| } | ||||||
| if (root->value == '*') | ||||||
| { | ||||||
| root->number = root->leftSon->number * root->rightSon->number; | ||||||
| } | ||||||
| if (root->value == '/') | ||||||
| { | ||||||
| root->number = root->leftSon->number / root->rightSon->number; | ||||||
| } | ||||||
| if (root->parent != NULL) | ||||||
| { | ||||||
| findAnswer(root->parent); | ||||||
| } | ||||||
| else | ||||||
| { | ||||||
| restoreField(root); | ||||||
| return; | ||||||
| } | ||||||
| } | ||||||
| else if (root->leftSon != NULL && compare(root->leftSon->value) && root->leftSon->help != '$') | ||||||
| { | ||||||
| findAnswer(root->leftSon); | ||||||
| } | ||||||
| else if (root->rightSon != NULL && compare(root->rightSon->value) && root->rightSon->help != '$') | ||||||
| { | ||||||
| findAnswer(root->rightSon); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| void printTree(Node* root) | ||||||
| { | ||||||
| if (root == NULL) | ||||||
| { | ||||||
| return; | ||||||
| } | ||||||
| printTree(root->leftSon); | ||||||
| printTree(root->rightSon); | ||||||
| printf("%c ", (root->value)); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| } | ||||||
|
|
||||||
| Node* rightSon(Node* root) | ||||||
| { | ||||||
| return root->rightSon; | ||||||
| } | ||||||
|
|
||||||
| Node* leftSon(Node* root) | ||||||
| { | ||||||
| return root->leftSon; | ||||||
| } | ||||||
|
|
||||||
| Node* parent(Node* root) | ||||||
| { | ||||||
| return root->parent; | ||||||
| } | ||||||
|
|
||||||
| char getValue(Node* root) | ||||||
| { | ||||||
| return root->value; | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| #pragma once | ||
|
|
||
| // Structure representing a tree | ||
| typedef struct Node Node; | ||
|
|
||
| // Function for creating a tree | ||
| Node* createTree(); | ||
|
|
||
| // Function for deleting a tree | ||
| void deleteTree(Node** root); | ||
|
|
||
| // Function that returns the root of the tree | ||
| Node* returnHead(Node* root); | ||
|
|
||
| // Function for building a tree | ||
| Node* buildTree(char* array); | ||
|
|
||
| // Function for calculating the value of an expression | ||
| void findAnswer(Node* root); | ||
|
|
||
| // Function for tree output | ||
| void printTree(Node* root); | ||
|
|
||
| // Function for returning the result of counting | ||
| int returnAnswer(Node* root); | ||
|
|
||
| // Function for accessing the right son of the current root | ||
| Node* rightSon(Node* root); | ||
|
|
||
| // Function for accessing the left son of the current root | ||
| Node* leftSon(Node* root); | ||
|
|
||
| // Function for accessing the parent of the current root | ||
| Node* parent(Node* root); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Не слишком ли много дерево раскрывает о себе? Сокрытие деталей реализации тут не очень, и принцип минимальности интерфейса абстракции тоже страдает |
||
|
|
||
| // Function to get the value | ||
| char getValue(Node* root); | ||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ну тоже переменные названы замечательно, непонятно, кто из них кто.