-
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 all 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()) | ||
| { | ||
| return -1; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,211 @@ | ||
| #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 symbol; | ||
| int expressionValues; | ||
| } Node; | ||
|
|
||
| typedef enum Direction | ||
| { | ||
| left, | ||
| right | ||
| } Direction; | ||
|
|
||
| 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* returnRoot(Node* node) | ||
| { | ||
| if (node == NULL) | ||
| { | ||
| return node; | ||
| } | ||
| while (node->parent != NULL) | ||
| { | ||
| node = node->parent; | ||
| } | ||
| return node; | ||
| } | ||
|
|
||
| bool isOperator(char symbol) | ||
| { | ||
| return symbol == '+' || symbol == '-' | ||
| || symbol == '*' || symbol == '/'; | ||
| } | ||
|
|
||
| void attach(Node* parent, Node* child, Direction direction) | ||
| { | ||
| if (parent == NULL) | ||
| { | ||
| return; | ||
| } | ||
| if (direction == left) | ||
| { | ||
| parent->leftSon = child; | ||
| } | ||
| else | ||
| { | ||
| parent->rightSon = child; | ||
| } | ||
| if (child != NULL) | ||
| { | ||
| child->parent = parent; | ||
| } | ||
| } | ||
|
|
||
| Node* createNode(char symbol) | ||
| { | ||
| Node* newNode = (Node*)calloc(1, sizeof(Node)); | ||
| if (newNode == NULL) | ||
| { | ||
| return NULL; | ||
| } | ||
| newNode->symbol = symbol; | ||
| newNode->expressionValues = isOperator(symbol) ? 0 : symbol - '0'; | ||
| return newNode; | ||
| } | ||
|
|
||
| Node* addNode(const char* array, int* counter, Node* node) | ||
| { | ||
| if (*counter > 0 && node == NULL) | ||
| { | ||
| return NULL; | ||
| } | ||
| while (array[*counter] == '(' || array[*counter] == ')' | ||
| || array[*counter] == ' ') | ||
| { | ||
| (*counter)++; | ||
| } | ||
| if (isOperator(array[*counter])) | ||
| { | ||
| Node* temporary = createNode(array[*counter]); | ||
| if (temporary == NULL) | ||
| { | ||
| node = returnRoot(node); | ||
| deleteTree(&node); | ||
| return NULL; | ||
| } | ||
| Node* operator = temporary; | ||
| (*counter)++; | ||
| attach(operator, addNode(array, counter, operator), left); | ||
| attach(operator, addNode(array, counter, operator), right); | ||
| return operator; | ||
| } | ||
| Node* operand = createNode(array[*counter]); | ||
| if (operand == NULL) | ||
| { | ||
| node = returnRoot(node); | ||
| deleteTree(&node); | ||
| return NULL; | ||
| } | ||
| (*counter)++; | ||
| return operand; | ||
| } | ||
|
|
||
| Node* buildTree(const char* array) | ||
| { | ||
| int counter = 0; | ||
| Node* node = NULL; | ||
| return addNode(array, &counter, node); | ||
| } | ||
|
|
||
| int findAnswer(Node* root, int* error) | ||
| { | ||
| if (*error != 0) | ||
| { | ||
| return 0; | ||
| } | ||
| if (root == NULL) | ||
| { | ||
| *error = 1; | ||
| return 0; | ||
| } | ||
| if (root->rightSon == NULL && root->leftSon == NULL) | ||
| { | ||
| return root->expressionValues; | ||
| } | ||
| if (root->leftSon != NULL) | ||
| { | ||
| root->leftSon->expressionValues = findAnswer(root->leftSon, error); | ||
|
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 (root->rightSon != NULL) | ||
| { | ||
| root->rightSon->expressionValues = findAnswer(root->rightSon, error); | ||
| } | ||
| if (root->rightSon != NULL && root->leftSon != NULL) | ||
| { | ||
| if (root->symbol == '+') | ||
| { | ||
| root->expressionValues = root->leftSon->expressionValues + root->rightSon->expressionValues; | ||
| } | ||
| if (root->symbol == '-') | ||
| { | ||
| root->expressionValues = root->leftSon->expressionValues - root->rightSon->expressionValues; | ||
| } | ||
| if (root->symbol == '*') | ||
| { | ||
| root->expressionValues = root->leftSon->expressionValues * root->rightSon->expressionValues; | ||
| } | ||
| if (root->symbol == '/') | ||
| { | ||
| root->expressionValues = root->leftSon->expressionValues / root->rightSon->expressionValues; | ||
| } | ||
| } | ||
| return root->expressionValues; | ||
| } | ||
|
|
||
| void printTreeRecursive(Node* root) | ||
| { | ||
| if (root == NULL) | ||
| { | ||
| return; | ||
| } | ||
| if (isOperator(root->symbol)) | ||
| { | ||
| printf("%c ", '('); | ||
| printf("%c ", root->symbol); | ||
| } | ||
| else if (root->parent != NULL && root->parent->rightSon == root) | ||
| { | ||
| printf("%c ", root->symbol); | ||
| printf("%c ", ')'); | ||
|
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. Да ну, проще было "если оператор, распечатать скобку, знак, вызваться рекурсивно от левого и правого сына, распечатать закрывающую скобку. Если операнд, просто число распечатать". |
||
| } | ||
| else | ||
| { | ||
| printf("%c ", root->symbol); | ||
| } | ||
| printTreeRecursive(root->leftSon); | ||
| printTreeRecursive(root->rightSon); | ||
| } | ||
|
|
||
| void printTree(Node* root) | ||
| { | ||
| printTreeRecursive(root); | ||
| printf("%c", ')'); | ||
| } | ||
|
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. Лучше было выводить в строку, потому что иначе эту функцию не протестировать, но ладно, пусть так |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| #pragma once | ||
|
|
||
| // Structure representing a tree | ||
| typedef struct Node Node; | ||
|
|
||
| // Function for deleting a tree | ||
| void deleteTree(Node** root); | ||
|
|
||
| // Function for building a tree | ||
| Node* buildTree(const char* array); | ||
|
|
||
| // Function for calculating the value of an expression | ||
| int findAnswer(Node* root, int* error); | ||
|
|
||
| // Function for tree output | ||
| void printTree(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.
Так "целые числа в качестве аргументов" не получится поддержать. Например, "-15".