这两天都没更, 主要是马上要连着要考三门(16, 18, 20), 都没时间学编译器了, 等过了这段时间应该能有很多时间来搞这个, 之后我准备先把之前写的那个词法分析器生成器改造一下, 弄个最简版的正则引擎出来玩玩, 不过这些都是后话了, 今天似乎也没什么时间, 也就把这单元的作业写了一下... 代码比较简单就不多做解释了...
1 #include <ctype.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 void parse_F(); 6 void parse_T(); 7 void parse_E(); 8 void error (char *want, char got); 9 10 int i; 11 char *str = 0; 12 13 void error (char *want, char got) 14 { 15 fprintf (stderr, "Compling this expression:\n%s\n", str); 16 int j = i; 17 while (j--) 18 fprintf (stderr, " "); 19 fprintf (stderr, "^\n"); 20 fprintf (stderr, "Syntax error at position: %d\n" 21 "\texpecting: %s\n" 22 "\tbut got : %c\n", 23 i, want, got); 24 exit (0); 25 return; 26 } 27 28 void parse_F() 29 { 30 char c = str[i]; 31 if (isdigit(c)){ 32 i++; 33 return; 34 } 35 if (c=='('){ 36 i++; 37 parse_E(); 38 c = str[i]; 39 if (c==')'){ 40 i++; 41 return; 42 } 43 error ("\')\'", c); 44 return; 45 } 46 error ("\'0-9\' or \'(\'", c); 47 return; 48 } 49 50 51 void parse_T() 52 { 53 parse_F(); 54 char c = str[i]; 55 while (c=='*' || c == '/'){ 56 i++; 57 parse_F(); 58 c = str[i]; 59 } 60 return; 61 } 62 63 void parse_E() 64 { 65 parse_T(); 66 char c = str[i]; 67 while (c =='+' || c == '-'){ 68 i++; 69 parse_T(); 70 c = str[i]; 71 } 72 return; 73 } 74 75 void parse (char *e) 76 { 77 str = e; 78 i = 0; 79 parse_E(); 80 if (str[i]=='\0') 81 return; 82 error ("\'+\' or '\\0\'", str[i]); 83 return; 84 } 85 /////////////////////////////////////////////// 86 // Your job: 87 // Add some code into the function parse_E() and 88 // parse_T to parse "-" and "/" correctly. 89 // When you finish your task, NO error message 90 // should be generated. 91 // Enjoy! :-P 92 int main (int argc, char **argv) 93 { 94 // There are the following rules on an expression: 95 // 1. Every expression is represented as a string; 96 // 2. integers are non-negative; 97 // 3. integers are between 0-9. 98 char *e; 99 100 e = "(2)"; 101 parse(e); 102 103 e = "(3+4*5))"; 104 parse(e); 105 106 e = "(8-2)*3"; 107 parse(e); 108 109 e = "(8-2)/3"; 110 parse(e); 111 112 return 0; 113 }