1 //
2 // Stack.h
3 // 顺序栈
4 //
5 // Created by geshenglu on 2020/3/21.
6 // Copyright © 2020 geshenglu. All rights reserved.
7 //
8
9 #ifndef Stack_h
10 #define Stack_h
11 template<class Elemtype>
12 class Stack
13 {
14 public:
15 virtual bool IsEmpty() const =0;
16 virtual void Push(const Elemtype&x)=0;
17 virtual Elemtype Pop()=0;
18 virtual Elemtype Top()const =0;
19 virtual ~Stack(){};
20 };
21 #endif /* Stack_h */
1 //
2 // SeqStack.h
3 // 顺序栈
4 //
5 // Created by geshenglu on 2020/3/21.
6 // Copyright © 2020 geshenglu. All rights reserved.
7 //
8
9 #ifndef SeqStack_h
10 #define SeqStack_h
11 #include "Stack.h"
12 template<class Elemtype>
13 class SeqStack:public Stack<Elemtype>
14 {
15 private:
16 Elemtype *data;
17 int maxSize;
18 int top_p;
19 void doubleSpace();
20 public:
21 SeqStack(int initSize = 10)
22 {
23 maxSize = initSize;
24 data = new Elemtype[maxSize];
25 top_p = -1;
26 }
27 ~SeqStack()
28 {
29 delete [] data;
30 }
31 virtual bool IsEmpty() const override;
32 virtual void Push(const Elemtype&x)override;
33 virtual Elemtype Pop()override;
34 virtual Elemtype Top()const override;
35 };
36
37 template<class Elemtype>
38 void SeqStack<Elemtype>::doubleSpace()
39 {
40 Elemtype *tmp = data;
41 data = new Elemtype[maxSize*2];
42 for (int i=0; i<maxSize; ++i)
43 data[i] = tmp[i];
44 maxSize *= 2;
45 delete tmp;
46 }
47
48 template<class Elemtype>
49 bool SeqStack<Elemtype>::IsEmpty() const
50 {
51 return top_p == -1;
52 }
53
54 template<class Elemtype>
55 void SeqStack<Elemtype>::Push(const Elemtype&x)
56 {
57 if(top_p == maxSize - 1)
58 {
59 doubleSpace();
60 }
61 data[++top_p]=x;
62 }
63
64 template<class Elemtype>
65 Elemtype SeqStack<Elemtype>::Pop()
66 {
67 return data[top_p--];
68 }
69
70
71 template<class Elemtype>
72 Elemtype SeqStack<Elemtype>::Top() const
73 {
74 return data[top_p];
75 }
76
77 #endif /* SeqStack_h */
1 //
2 // Balance.h
3 // 括号匹配
4 //
5 // Created by geshenglu on 2020/3/25.
6 // Copyright © 2020 geshenglu. All rights reserved.
7 //
8
9 #ifndef Balance_h
10 #define Balance_h
11 #include <fstream>
12 class Balance{
13 std::ifstream fin;
14 int currentLine;
15 int Errors;
16 struct Symbol{
17 char Token;
18 int TheLine;
19 };
20 enum class CommentTpye{
21 SlashSlash,
22 SlashStar
23 };
24 bool CheckMatch(char Symba1,char Symba2,int Line1,int Line2);
25 char GetNextSymbol();
26 void PutBackChar(char ch);
27 void SkipComment(enum class CommentTyp type);
28 void SkipQuote(char type);
29 char NextChar();
30 public:
31 Balance(const char *s);
32 int CheckBalance();
33 class NoFile{};
34 };
35
36 #endif /* Balance_h */
1 //
2 // Balance.cpp
3 // 括号匹配
4 //
5 // Created by geshenglu on 2020/3/25.
6 // Copyright © 2020 geshenglu. All rights reserved.
7 //
8
9 #include "Balance.h"
10 #include "SeqStack.h"
11 #include <iostream>
12 Balance::Balance(const char *s){
13 fin.open(s);
14 if(!fin)
15 throw NoFile();
16 currentLine = 1;
17 Errors = 0;
18 }
19
20 int Balance::CheckBalance(){
21 struct Symbol node;
22 SeqStack<Symbol> stack;
23 char lastChar,match;
24 while(lastChar = GetNextSymbol()){
25 switch (lastChar) {
26 case '{':case '[':case '(':
27 node.Token = lastChar;
28 node.TheLine = currentLine;
29 stack.Push(node);
30 break;
31 case '}':case '}':case ')':
32 if (stack.IsEmpty()) {
33 ++Errors;
34 std::cout<<"在第"<<currentLine<<"有一个多余的"<<lastChar<<std::endl;
35 }
36 else{
37 node = stack.Pop();
38 match = node.Token;
39 if(!CheckMatch(match, lastChar, node.TheLine, currentLine))
40 ++Errors;
41 }
42 break;
43 }
44 }
45 while (!stack.IsEmpty()) {
46 ++Errors;
47 node = stack.Pop();
48 std::cout<<"在第"<<node.TheLine<<"行的符号"<<node.Token<<"不匹配!"<<std::endl;
49 }
50 return Errors;
51 }
52
53 bool Balance::CheckMatch(char Symba1,char Symba2,int Line1,int Line2){
54 if(Symba1=='{'&&Symba2!='}'||Symba1=='('&&Symba2!=')'||Symba1=='['&&Symba2!='}'){
55 std::cout<<"发现第"<<Line1<<"行的符号"<<Symba1<<"与第"<<Line2<<"行的符号不匹配"<<std::endl;
56 return false;
57 }
58 return true;
59 }
60
61 char Balance::GetNextSymbol(){
62 char ch;
63 while (ch = NextChar()) {
64 if(ch == '\'){
65 ch = NextChar();
66 if(ch == '\'){
67 SkipComment(SlashSlash);
68 }
69 else if(ch == '*')
70 SkipComment(SlashStar);
71 else
72 PutBackChar(ch);
73 }
74 else if(ch == '\''||ch == '"'){
75 SkipQuote(ch);
76 }
77 else if(ch == '('||ch == '{'||ch == '['){
78 return ch;
79 }
80 }
81 return nullptr;
82 }
83
84 void Balance::PutBackChar(char ch){
85 fin.putback(ch);
86 if(ch == '\n')
87 --currentLine;
88 }
89
90 void Balance::SkipComment(enum CommentType type){
91 char ch,flag;
92 if(type == SlashSlash){
93 while (ch = NextChar() && ch != '\n');
94 return;
95 }
96 flag = '';
97 while((ch = NextChar())!= nullptr){
98 if(flag == '*' && ch == '/')
99 return;
100 flag = ch;
101 }
102 ++Errors;
103 std::cout<<"Comment is unterminated!"<<std::endl;
104 }
105
106 void Balance::SkipQuote(char type){
107 char ch;
108 while(ch = NextChar()){
109 if(ch == type)
110 return;
111 else if (ch == '\n'){
112 ++Errors;
113 std::cout<<"missing closing quote at line"<<currentLine<<std::endl;
114 return;
115 }
116 else if(ch == '\\')
117 ch = NextChar();
118 }
119 }
120
121 char Balance::NextChar(){
122 char ch;
123 if((ch = fin.get())==EOF)
124 return nullptr;
125 if(ch == '\n')
126 ++currentLine;
127 return ch;
128 }
1 //
2 // main.cpp
3 // 括号匹配
4 //
5 // Created by geshenglu on 2020/3/25.
6 // Copyright © 2020 geshenglu. All rights reserved.
7 //
8
9 #include <iostream>
10 #include "Balance.h"
11 using namespace std;
12
13 int main(int argc, const char * argv[]) {
14 char fileName[80];
15 Balance *p;
16 int result;
17 try{
18 if(argc == 1){
19 cout<<"请输入文件名:"<<endl;
20 cin>>fileName;
21 p = new Balance(fileName);
22 result = p->CheckBalance();
23 delete p;
24 cout<<"共"<<result<<"个错误!"<<endl;
25 return 0;
26 }
27 while(--argc){
28 cout<<"检查文件"<<*++argv<<endl;
29 p = new Balance(*argv);
30 result = p->CheckBalance();
31 delete p;
32 cout<<"共"<<result<<"个错误!"<<endl;
33 }
34 }
35 catch (Balance::NoFile){
36 cout<<"no catch file"<<endl;
37 }
38
39 return 0;
40 }