The Link Your Class | https://bbs.csdn.net/forums/MUEE308FZU202201 |
---|---|
The Link of Requirement of This Assignment | https://bbs.csdn.net/topics/608734907 |
The Aim of This Assignment | extract keywords of different levels from the C |
MU STU ID and FZU STU ID | 20122578_832002129 |
CONTENT
1.📋PSP form
Personal Software Process Stages | Estimated time(min) | Real time(min) |
---|---|---|
Planning | 10 | 5 |
Estimate | 100 | 97 |
Development | 80 | 100 |
Analysis | 5 | 6 |
Design Spec | 10 | 8 |
Design Review | 10 | 2 |
Coding Standard | 5 | 3 |
Design | 40 | 50 |
Coding | 40 | 50 |
Code Review | 20 | 20 |
Test | 30 | 20 |
Test Report | 10 | 5 |
Size Measurement | 5 | 5 |
Postmortem & Process Improvement Plan | 50 | 55 |
Total | 415 | 426 |
2.Problem analysis
2.1.Level choose
First of all, the topic gives us four different levels of choice, and here we need to design a logical block for the input level.
It should be noted that the high-level level contains what the low-level level needs to achieve.
If choose if_elseif_else blocks, need to set one layer at a time, which is more troublesome.
Therefore, be prepared to select the switch block for level choose.
2.2.Level1 implementation
The topic requires us to count the total number of keywords in the code, so first we need to count all the keywords defined in C.
Search for C language keywords in Baidu.
There are 32 basic keywords, which are:
auto | break | case | char | const | continue | default | do |
---|---|---|---|---|---|---|---|
double | else | enum | extern | float | for | goto | if |
int | long | register | return | short | signed | sizeof | static |
struct | switch | typedef | union | unsigned | void | volatile | while |
On December 16, 1999, ISO launched the C99 standard, which added five new C language keywords:
inline | restrict | _Bool | _Complex | _Imaginary |
---|
On December 8, 2011, ISO released a new standard for C language, C11, which added 7 new C language keywords:
_Alignas | _Alignof | _Atomic | _Static_assert | _Noreturn | _Thread_local | _Generic |
---|
Therefore, there are a total of 44 keywords, which are extracted and stored in the file for subsequent keyword statistics.
The basic decision is to use the String method for line-by-line statistics in code.
2.3.Level2 implementation
This block is the count of the case blocks contained in the Switch block and each Switch logic block in the code.
Just record the number of case blocks after finding the new Switch keyword, and continue with the case keyword search.
2.4.Level3 implementation
This block is a search statistic for logical blocks that contain only if_else, because it contains only information, so it is necessary to distinguish whether it contains elseif or not.
To achieve this, the idea of the stack can be utilized. And the basic element of the stack is boolean
When the if is read, it is placed on the stack.
When elseif is read, remove the if from the stack, set it as include elseif, and put it back on the stack.
When else is read, take if from the stack to check whether elseif is included, count if it does not, and discard it directly if it does.
Note that if the code is not standardized, such as containing only if and no else, it cannot be logged.
2.5.Level4 implementation
This block is to find statistics on logical blocks containing elseif, and when it does not contain elseif, no statistics are made.
The implementation of Level 4 is close to the implementation of Level 3, and you can also take advantage of the idea of the stack.
The difference is only that when the else is read, take the if from the stack to see if it is set to contain elseif, if it does, count it, and discard it if it does not.
Similar to above, if the code is not standardized, such as containing only if and elseif and no else, it cannot be logged.
2.6.User interface design
This piece is additionally added for better human-computer interaction.
3.Design and implementation process
3.1development platform
Use the Java language for program development and the Java language for GUI interface development
Development platform: Eclipse
3.2.Code organization
In summary, the code implementation of this experiment is divided into three blocks in total.
One is about the Switch logic block judgment of the level, one is about the code for the functions implemented for different levels, and the last one is about the development of the user interface.
It is worth noting that since LEVEL3 and LEVEL4 are implemented in a similar way, the methods of LEVEL3 and 4 were chosen to be merged in order to optimise the code.
3.3.flow chart
4.Code details
4.1.PART 1
As previously stated, the purpose of this piece of code is to achieve that when a high level LEVEL is entered, a low level LEVEL will be achieved at the same time. A flow chart follows to illustrate:
The initial value of LEVEL here is 0. When the value 0 is encountered, it will simply be error.
switch(level) {
case 4:
case 3:
level_3_4(temp);
case 2:
level_2(temp);
case 1:
level_1(temp);
break;
default::
return "LEVEL is not choiced";
}
4.2.PART 2
4.2.1.Level 1
The key to implementing LEVEL1 is the excerpting of keywords and the detection of whether the segment contains keywords through the String method.
public void level_1(String s) {
//the keywords defined in the table
String[] keyword={"auto","break","case","char","const","continue","default","do ",//distinguish do and double
"double","else","enum","extern","float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static","struct","switch","typedef","union",
"unsigned","void","volatile","whlie","inline","restrict","_Bool","_Complex","_Imaginary",
"_Alignas","_Alignof","_Atomic","_Static_assert","_Noreturn","_Thread_local","_Generic"};
for(int i = 0;i<keyword.length;i++) if(s.contains(keyword[i])) keyNum++;
}
4.2.2.Level 2
The key to implementing LEVEL2 is the detection of the Switch keyword. When a new Switch keyword is detected, the case keyword contained in the previous Switch keyword is stored in the chain.
public void level_2(String s) {
if(s.contains("switch")) {
//chain
caseNum.add(cNum);
//The temp integer
cNum=0;
switchNum++;
}
if(s.contains("case")) cNum++;
}
4.2.3.Level 3 and 4
The key to implementing LEVEL3 and 4 is to store the keyword if, when encountered, adding to a set stack. When an elseif keyword is encountered, it is taken out and set to true and put back in. When the else keyword is encountered, it is removed and judged by the boolean value.
public void level_3_4(String s) {
if(!s.contains("else if")) {
//When meet the if
if(s.contains("if")) {
stack.add(false);
}
//When meet the else
if(s.contains("else")) {
if(!stack.pop()) {
else_block++;
}else {
elseif_block++;
}
}
//When meet the elseif
}else {
stack.pop();
stack.add(true);
}
}
4.2.4.OUTPUT
String feedback according to different LEVEL values.
public String output(int level) {
String ans="";
switch(level) {
case 4:
ans="\nif-elseif-else num: "+elseif_block+ans;
case 3:
ans="\nif-else num: "+else_block+ans;
case 2:
ans=(" "+cNum)+ans;
for(int i=caseNum.size()-1;i>0;i--) {
ans=(" "+caseNum.get(i))+ans;
}
ans=("\ncase num:")+ans;
ans="\nswitch num: "+switchNum+ans;
case 1:
ans=("Total num: "+keyNum)+ans;
}
return ans;
}
4.3.PART 3
The basic components of the event handling and user interface are designed to implement a GUI interface for interaction with objects.
4.3.1.Path input
Use the text component to get the file path.
JPanel pn1 = new JPanel();
pn1.setBounds(0,0,385,60);
pn1.setBorder(BorderFactory.createTitledBorder("Please input the file path:"));
JTextField setpath = new JTextField("e.g. C:\\Users\\Apple\\Desktop\\c_testfile.txt",30);
pn1.add(setpath);
4.3.2.Level choose
Use the button component to choose the level.
JPanel pn2 = new JPanel();
pn2.setBounds(0,60,385,60);
pn2.setBorder(BorderFactory.createTitledBorder("Please choose the level you want:"));
pn2.setLayout(new GridLayout(2,2));
JRadioButton bn1 = new JRadioButton("level 1");
JRadioButton bn2 = new JRadioButton("level 2");
JRadioButton bn3 = new JRadioButton("level 3");
JRadioButton bn4 = new JRadioButton("level 4");
pn2.add(bn1);
pn2.add(bn2);
pn2.add(bn3);
pn2.add(bn4);
//Set in a button group
ButtonGroup bn = new ButtonGroup();
bn.add(bn1);
bn.add(bn2);
bn.add(bn3);
bn.add(bn4);
4.3.3.ActionListener
Listening for click events with actionlistener
begin.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Extract ex = new Extract();
String path;
int level = 0;
if (e.getSource() == begin)
{
path = setpath.getText();
if(bn1.isSelected()) {
level = 1;
}else if(bn2.isSelected()) {
level = 2;
}else if(bn3.isSelected()) {
level = 3;
}else if(bn4.isSelected()) {
level = 4;
}
out.setText(ex.answer(path,level));
}
}
});
5.Unit test
Uniform use of conditional coverage for unit test.
5.1.PART 1 and 2
Since PART1 and PART2 are closely integrated, the two are tested together as a unit.
This test will refer to the flow chart above for full path coverage.
For the test code, only one file was covered as the teacher only provided one test case.
Extract e=new Extract();
int[] level= {0,1,2,3,4};
String path="C:\\\\Users\\\\Apple\\\\Desktop\\\\c_testfile.txt";
for (int i = 0; i < level.length; i++) {
System.out.println("Test begin\n");
System.out.println(e.answer(path,level[i])+"\n");
System.out.println("Test over\n------------------------------");
}
The output is shown below:
5.2.PART 3
The results of the user interface are as follows:
After entering the parameters, the following results are displayed:
6.Coverage optimization and performance optimization
6.1.Coverage optimization
6.1.1.Basic realization
This coverage optimisation is for LEVEL 3 & 4 where some users have code irregularities that affect coverage. For example, some code may contain only an if without an else as the end.
To achieve this, the “if”, “elseif” and “else” keywords are detected and placed on the stack. When “}” is read, the keyword is removed from the stack, enabling a hierarchy of logical nesting.
The essence of the method is to use the “}” as a signal for the end of the logical block. Also, the “if_elseif_else” logic block is distinguished from the “if_else” logic block by checking whether the same hierarchy contains the “ifelse” keyword.
The detailed flow chart is shown below:
The actual code is shown below:
public void level_3_4_optimization(String s) {
//keyword detect
if(!s.contains("else if")) {
if(s.contains("if")) {
//increase the level
stack.add("if"+level++);
}
if(s.contains("else")) {
stack.add("else"+level++);
}
}else {
stack.add("elseif"+level++);
}
if(s.contains("}")){
now = stack.pop();
if(now.contains("elseif")) {
if(!now.equals(pre)) {
elseif_block++;
}
}else if(now.contains("if")) {
total++;
}
level--;
pre = now;
}
}
Tested against the following partial c code blocks:
if(i<0){
if(i<-1){}
else{}
}
else if(i>0){
if (i>2){}
else if (i==2) {}
else if (i>1) {}
}
else{
if(j!=0){}
}
The test results are as follows:
6.1.2.Further
Further optimisation can be achieved here by adding the following code to the above code.
if(s.contains("main")||s.contains("switch")) {
stack1.add("anotherwords"+level++);
}
With the addition of more keyword recognition containing “{}”, the code can be continually optimised for coverage.
6.2.Performance testing and performance optimization
6.2.1.Computational performance testing
This test gives the time required to execute the method.
This test will make the code run 10000 times repeatedly at level 4, and eventually obtain an average value to represent the running time.
System.out.println("Here is the computational performance testing\nTest begin-------------------------------\n");
long start=System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
Extract e = new Extract();
e.answer("C:\\Users\\Apple\\Desktop\\c_testfile.txt",4);
}
long end=System.currentTimeMillis();
double ans=(double)(end-start)/10000;
System.out.println("time lasts "+ans+"ms");
System.out.println("\nTest end-------------------------------");
The results are shown in the graph below:
6.2.2.Memory consumption testing
The test code is as follows:
public static void start() {
System.out.println("Here is the memory consumption testing");
System.out.println("-------------------------------\n");
//得到虚拟机运行、程序开始执行时jvm所占用的内存。
Runtime runtime = Runtime.getRuntime();
concurrentMemory1 = runtime.totalMemory()-runtime.freeMemory();
}
public static void end() {
//得到虚拟机运行、所要测试的执行代码执行完毕时jvm所占用的内存(byte)。
Runtime runtime = Runtime.getRuntime();
concurrentMemory2 = runtime.totalMemory()-runtime.freeMemory();
String memory = String.valueOf((double)(concurrentMemory2-concurrentMemory1)/1024);
System.out.println("The memory consumption is "+memory+" KB");
System.out.println("\nTest end-------------------------------");
}
The test results are as follows:
Visible memory consumption is low.
6.2.3.Performance optimisation
The assignment is relatively simple and there are no optimisation options available at this time.
7.Summary
This experiment resulted in the creation of a complete small project, obtaining an executable file of type jar, which could be run independently on a computer with a java environment.
Although the experiments were simple, a number of optimisations were considered and attempted in the process, and I hope to further improve my personal skills in the next few days
The source code has been committed to github.