comparison c/regexParser/main.cc @ 56:8901bc071d33

implement string() and literal()
author Masataka Kohagura <kohagura@cr.ie.u-ryukyu.ac.jp>
date Thu, 11 Jun 2015 16:24:40 +0900
parents 883e3473a9f5
children 71b497d25273
comparison
equal deleted inserted replaced
55:883e3473a9f5 56:8901bc071d33
1 /* 1 /*
2 Very Simple Calculator 2 * <literal> ::= [a-z][A-Z][0-9]
3 $Id$ 3 * <charClass> ::= '['<literal>'-'<literal>']'
4 * <string> ::= <literal><literal>*
5 * <or> ::= '('<regex>'|'<regex>')'
6 * <*> ::= <regex>'*'
7 * <regex> ::= <literal>|<conc>|<or>|<charClass>
4 */ 8 */
5 9
6 #include <stdio.h> 10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 char *ptr;
7 14
8 static char *ptr,*last_ptr; 15 typedef struct node {
9 static int value,lvalue; 16 int character;
10 static int last_token; 17 struct node *left;
11 static int variable[48]; 18 struct node *right;
19 } Node, *NodePtr;
12 20
13 static int expr(); 21 NodePtr charClass();
14 static int aexpr(); 22 NodePtr string();
15 static int mexpr(); 23 NodePtr _or();
16 static int term(); 24 NodePtr asterisk();
17 static int token(); 25 NodePtr regex();
18 static void error(char *); 26 NodePtr createNode(int,NodePtr,NodePtr);
19 27
28 NodePtr createNode(int character, NodePtr left, NodePtr right) {
29 NodePtr n;
30 n = (NodePtr)malloc(sizeof(Node));
31 n->character = character;
32 n->left = left;
33 n->right = right;
34 return n;
35 }
20 36
21 static int 37 // <charClass> ::= '['<literal>'-'<literal>']'
22 token() 38 NodePtr charClass() {
23 { 39 NodePtr n = createNode(0,0,0);
24 int c,d; 40 return n;
41 }
25 42
26 last_ptr = ptr; /* for error position */ 43 // <literal> ::= [a-z][A-Z][0-9]
27 c= *ptr; 44 NodePtr literal() {
28 if(!c) { 45 char c = *ptr;
29 last_token = EOF; 46 createNode(c,0,0);
30 return last_token; 47 }
31 }
32 ptr++;
33 if (c<=' ') { /* comment */
34 while(*ptr++);
35 ptr--;
36 last_token = EOF;
37 last_ptr = ptr;
38 return last_token;
39 }
40 48
41 if('0'<=c && c<='9') { /* Decimal */ 49 // <string> ::= <literal><literal>*
42 d = c-'0'; 50 NodePtr string() {
43 while((c= *ptr++)) { 51 char c = *ptr;
44 if('0'<=c && c<='9') { 52 NodePtr n = (NodePtr)malloc(sizeof(Node));
45 d = d*10 + (c - '0');
46 } else {
47 break;
48 }
49 }
50 c && ptr--;
51 value = d;
52 last_token = '0';
53 return last_token;
54 53
55 } else if ('a'<=c && c<='z') { /* variable */ 54 if (('a'<=c && c<='z')||('A'<=c && c<='Z')||('0'<=c && c<='9')) {
56 value = c-'a'; /* return variable reference */ 55 n = createNode(0,literal(),string());
57 last_token = 'v'; 56 return n;
58 return last_token;
59 } else { 57 } else {
60 last_token = c; 58 n = createNode(0,0,0);
61 return last_token;
62 return c;
63 } 59 }
64 } 60 }
65 61
66 static int 62 // <or> ::= '('<regex>'|'<regex>')'
67 expr() 63 NodePtr _or() {
68 { 64 regex();
69 int d,assign; 65 while(*ptr++ == ')') {
70 66 if (*ptr == '|') {
71 d = aexpr(); 67 ptr++;
72 assign = lvalue; 68 regex();
73 switch(last_token) {
74 case '>':
75 d = (d > aexpr());
76 return d;
77 case '=':
78 if(assign>=0) {
79 d = expr();
80 variable[assign] = d;
81 return d;
82 } else {
83 error("Bad assignment");
84 return 0;
85 } 69 }
86 case ')':
87 return d;
88 case EOF:
89 return d;
90 default:
91 error("Bad expression");
92 return d;
93 } 70 }
94 } 71 }
95 72
96 static int 73 // <*> ::= <regex>'*'
97 aexpr() 74 NodePtr asterisk() {
98 {
99 int d;
100 75
101 d = mexpr();
102 switch(last_token) {
103 case '-':
104 d -= aexpr();
105 return d;
106 case '+':
107 d += aexpr();
108 return d;
109 default:
110 return d;
111 }
112 } 76 }
113 77
114 static int 78 // <regex> ::= <literal>|<string>|<or>|<charClass>
115 mexpr() 79 // <literal> は <string> に内包されるから、<regex> ::= <string>|<or>|<charClass>が正しい??
116 { 80 NodePtr regex() {
117 int d; 81
118 d = term(); 82 NodePtr n;
119 switch(last_token) { 83
120 case '*': 84 while (int c = *ptr++) {
121 d *= mexpr(); 85 if (c == '(') {
122 return d; 86 ptr++;
123 case '/': 87 _or();
124 d /= mexpr(); 88 } else if (c == '[') {
125 return d; 89 charClass();
126 default: 90 } else {
127 return d; 91 n = createNode(0,string(),regex());
92 }
128 } 93 }
129 }
130 94
131 static int 95 return n;
132 term()
133 {
134 int d;
135
136 lvalue= -1;
137 token();
138 if(last_token==EOF) {
139 error("Term expected");
140 }
141 switch(last_token) {
142 case '0':
143 d = value;
144 token();
145 return d;
146 case 'v':
147 d = lvalue = value;
148 token();
149 return variable[d];
150 case '(':
151 d = expr();
152 if(last_token != ')') {
153 error("Unbalanced parenthsis");
154 }
155 token();
156 return d;
157 default:
158 token();
159 error("Unknown term");
160 return 0;
161 }
162 }
163
164 static int lineno = 0;
165
166 void
167 error(char *msg)
168 {
169 fprintf(stderr,"%s on line %d\n",msg, lineno);
170 } 96 }
171 97
172 int 98 int
173 main() 99 main(int argc, char **argv)
174 { 100 {
175 int d; 101 for (int i = 1; i < argc; i++) {
176 char buf[BUFSIZ]; 102 if (strcmp(argv[i],"-regex") == 0) {
103 ptr = argv[i+1]; i++;
104 }
105 }
177 106
178 while (fgets(buf,BUFSIZ,stdin)) { 107 printf("regex : %s\n",ptr);
179 ptr = buf; 108 NodePtr n = regex();
180 d = expr(); 109
181 printf("%s = 0x%08x = %d\n",buf,d,d);
182 fflush(stdout);
183 lineno++;
184 }
185 return 0; 110 return 0;
186 } 111 }