Coding 生涯已经有1年4个月了,虽然比较熟悉公司框架,用起来还比较熟练,但是回头想想,其实自己还是停留在新手阶段,与刚出学校的那些“大侠”们不相上下。特别是昨天看到我们的CTO-BridGu(相信去过javaeye的朋友没有不知道这个名字的吧)给我改写的一段程序以后,感觉自己的程序是那么的幼稚。丝毫没有professional的感觉,很是惭愧!
这个功能是一个解析String生成function的功能,当然格式要求非常严格的,而且格式验证也是一个不可缺少,而且是非常重要的环节。
不知道你看到这个功能脑子里面想到是什么样的解决方案呢?我没有多想,拿起来就当String来处理,split, substring etc.
看看程序吧:
下面是我的方法,暂且说是方法吧:
1 public void addFunction(String prototype,Long comId)throws AlpineException{
2 ModDao dao = (ModDao)this.getDao("modDao");
3 Components com = this.findByPrimaryKey(Components.class, comId);
4 Functions function = new Functions();
5 function.setComponent(com);
6 prototype = delDupSpace(prototype);
7 String[] funTtemp = prototype.split("\n");
8 String fun = funTtemp[0];
9 if(fun.indexOf("(") == -1||fun.indexOf(")") == -1){
10 throw new AlpineException(ErrorCode.FUNCTION_FORMAT_ERROR);
11 }
12 String funHead = fun.substring(0,fun.indexOf("("));
13 String[] typeAndHead = funHead.split(" ");
14 if(typeAndHead.length < 1){
15 throw new AlpineException(ErrorCode.FUNCTION_FORMAT_ERROR);
16 }else{
17 if(typeAndHead.length >1){
18 function.setReturnType(typeAndHead[0]);
19 function.setFunctionName(typeAndHead[typeAndHead.length-1]);
20 }else{
21 function.setReturnType("void");
22 function.setFunctionName(typeAndHead[0]);
23 }
24 if(fun.indexOf("//") != -1){
25 String exp = fun.substring(fun.indexOf(";")+1);
26 exp = exp.replaceAll(" ", "");
27 function.setExplanation(exp);
28 }
29 this.insert(function);
30
31 String paStr = fun.substring(fun.indexOf("(")+1, fun.indexOf(")"));
32 if(!StringHelper.isEmpty(paStr)){
33 String[] pas = paStr.split(",");
34 for (int i = 0; i < pas.length; i++) {
35 Parameters parameter = new Parameters();
36 String[] pars = pas[i].split(" ");
37 if(pars.length < 2 || pars.length > 3){
38 throw new AlpineException(ErrorCode.FUNCTION_FORMAT_ERROR);
39 }else{
40 if(pars.length == 2){
41 Parameters paDup = dao.getParameterByPaName(pars[1], function.getId());
42 if(paDup != null)
43 throw new AlpineException(ErrorCode.FUNCTION_FORMAT_ERROR);
44
45 parameter.setParameterName(pars[1]);
46 parameter.setParameterType(pars[0]);
47 parameter.setInOrOut("In");
48 }
49 if(pars.length == 3){
50 Parameters paDup = dao.getParameterByPaName(pars[2], function.getId());
51 if(paDup != null)
52 throw new AlpineException(ErrorCode.FUNCTION_FORMAT_ERROR);
53
54 parameter.setParameterName(pars[2]);
55 parameter.setParameterType(pars[1]);
56 if(pars[0].contains("In"))
57 parameter.setInOrOut("In");
58 if(pars[0].contains("Out"))
59 parameter.setInOrOut("Out");
60 }
61 parameter.setFunction(function);
62 this.insert(parameter);
63 parameter.setOrderF(parameter.getId());
64 this.update(parameter);
65 }
66 }
67 }
68
69 for (int i = 1; i < funTtemp.length; i++) {//start 1
70 String[] paTemp = funTtemp[i].split(":");
71 if(paTemp.length == 2){
72 Parameters parameter = dao.getParameterByPaName(paTemp[0].trim(),function.getId());
73 if(parameter != null){
74 parameter.setExplanation(paTemp[1]);
75 this.update(parameter);
76 }
77 }
78 }
79 }
80 }
以下是BirdGu的方案:
1public class FunctionParser {
2 public static class Token {
3 private TokenType type;
4 private String content;
5 public Token(TokenType type, String content) {
6 super();
7 this.type = type;
8 this.content = content;
9 }
10 public String getContent() {
11 return content;
12 }
13 public TokenType getType() {
14 return type;
15 }
16
17
18 }
19
20 private enum TokenType {symbol, leftParenthese, rightParenthese, inOutFlag, comment, comma};
21 private enum TokenParseStatus {start, inSymbol, comment1, inOutFlag};
22
23 private interface ParseStatus {
24 public ParseStatus process (Functions function, Token token, Stack<String> symbolStack)
25 throws InvalidSyntaxException;
26 }
27
28 private static final ParseStatus START = new ParseStatus() {
29 public ParseStatus process(Functions function, Token token, Stack<String> symbolStack)
30 throws InvalidSyntaxException {
31 if (token.getType() == TokenType.symbol) {
32 symbolStack.push(token.getContent());
33 return GOT_FIRST_SYMBOL;
34 }
35 throw new InvalidSyntaxException (token);
36 }
37 };
38
39 private static final ParseStatus GOT_FIRST_SYMBOL = new ParseStatus () {
40 public ParseStatus process(Functions function, Token token, Stack<String> symbolStack) throws InvalidSyntaxException {
41 if (token.getType() == TokenType.leftParenthese) {
42 function.setReturnType("void");
43 function.setFunctionName(symbolStack.pop());
44 return WAITING_FIRST_ARG;
45 } else if (token.getType() == TokenType.symbol) {
46 function.setFunctionName(token.getContent());
47 function.setReturnType(symbolStack.pop());
48 return BEFORE_ARG_DEF;
49 }
50 throw new InvalidSyntaxException (token);
51 }
52 };
53
54 private static final ParseStatus BEFORE_ARG_DEF = new ParseStatus () {
55 public ParseStatus process(Functions function, Token token, Stack<String> symbolStack) throws InvalidSyntaxException {
56 if (token.getType() == TokenType.leftParenthese) {
57 return WAITING_FIRST_ARG;
58 }
59 throw new InvalidSyntaxException (token);
60 }
61 };
62
63 private static final ParseStatus WAITING_FIRST_ARG = new ParseStatus () {
64
65 public ParseStatus process(Functions function, Token token, Stack<String> symbolStack) throws InvalidSyntaxException {
66 if (token.getType() == TokenType.rightParenthese) {
67 return AFTER_ARG_DEF;
68 } else if (token.getType() == TokenType.symbol) {
69 symbolStack.push(token.getContent());
70 return GOT_ARG_TYPE;
71 } else if (token.getType() == TokenType.inOutFlag) {
72 symbolStack.push (token.getContent());
73 return GOT_IN_OUT_FLAG;
74 }
75 throw new InvalidSyntaxException (token);
76 }
77 };
78
79 private static final ParseStatus GOT_IN_OUT_FLAG = new ParseStatus () {
80 public ParseStatus process(Functions function, Token token, Stack<String> symbolStack) throws InvalidSyntaxException {
81 if (token.getType() == TokenType.symbol) {
82 symbolStack.push(token.getContent());
83 return GOT_ARG_TYPE;
84 }
85 throw new InvalidSyntaxException (token);
86 }
87 };
88
89 private static final ParseStatus GOT_ARG_TYPE = new ParseStatus () {
90 public ParseStatus process(Functions function, Token token, Stack<String> symbolStack) throws InvalidSyntaxException {
91 if (token.getType() == TokenType.symbol) {
92 Parameters param = new Parameters ();
93 param.setParameterName(token.getContent());
94 param.setParameterType(symbolStack.pop());
95 String inOutFlag = "In";
96 if (!symbolStack.isEmpty()) {
97 inOutFlag = symbolStack.pop();
98 }
99 param.setInOrOut(inOutFlag);
100 function.adParameter(param);
101 return GOT_ARG_VALUE;
102 }
103 throw new InvalidSyntaxException (token);
104 }
105 };
106
107 private static final ParseStatus GOT_ARG_VALUE = new ParseStatus () {
108 public ParseStatus process(Functions function, Token token, Stack<String> symbolStack) throws InvalidSyntaxException {
109 if (token.getType() == TokenType.rightParenthese) {
110 return AFTER_ARG_DEF;
111 } else if (token.getType() == TokenType.comma) {
112 return WAITING_ARG;
113 }
114 throw new InvalidSyntaxException (token);
115 }
116 };
117
118 private static final ParseStatus WAITING_ARG = new ParseStatus () {
119 public ParseStatus process(Functions function, Token token, Stack<String> symbolStack) throws InvalidSyntaxException {
120 if (token.getType() == TokenType.symbol) {
121 symbolStack.push(token.getContent());
122 return GOT_ARG_TYPE;
123 } else if(token.getType() == TokenType.inOutFlag) {
124 symbolStack.push(token.getContent());
125 return GOT_IN_OUT_FLAG;
126 }
127 return null;
128 }
129 };
130
131 private static final ParseStatus AFTER_ARG_DEF = new ParseStatus () {
132 public ParseStatus process(Functions function, Token token, Stack<String> symbolStack) throws InvalidSyntaxException {
133 if (token.getType() == TokenType.comment) {
134 function.setExplanation(token.getContent());
135 return END;
136 }
137 throw new InvalidSyntaxException (token);
138 }
139 };
140
141 private static final ParseStatus END = new ParseStatus () {
142 public ParseStatus process(Functions function, Token token, Stack<String> symbolStack) throws InvalidSyntaxException {
143 throw new InvalidSyntaxException (token);
144 }
145 };
146
147 private StringBuffer currentLine;
148 private int index;
149 private Functions function;
150
151 public Functions parse(String content) throws InvalidSyntaxException {
152 if (StringHelper.isEmpty(content)) {
153 throw new IllegalArgumentException ("content is empty.");
154 }
155 StringTokenizer tokenizer = new StringTokenizer (content, "\n");
156 String line = tokenizer.nextToken();
157 parseFirstLine (line);
158 while (tokenizer.hasMoreTokens()) {
159 line = tokenizer.nextToken();