- 论坛徽章:
- 0
|
编译领域初学者,看了几天书,并参考了一些资料,花了两个多小时做了一个简单的计算器,支持(),不支持空格,计算对象不大于10,主要是想省掉词法分析这步骤,直接体会一下语法分析。有一些疑问,就是指定syntax rule的时候,像这样自己包含自己的(expr 包含 expr)怎么写代码好expr := expr oper_level_2 term | term
虽然有现成的可以参考,但似乎没有掌握。
一开始写的时候我竟然这样
int expr(void)
{
expr()
while(1) {
do something
...
}
} |
那位先辈给说明一下。
以下是我的code,也麻烦请指点指点。
/*
<syntax rule>
expr := expr oper_level_2 term | term
term := term oper_level_1 factor | factor
oper_level_2 := +|-
oper_level_1 := *|/
factor := 0|1|2|3|4|5|6|7|8|9|(expr)
*/
#define LENGTH 1000
int i = 0;
char buf[LENGTH];
char token;
void error(char *str)
{
printf("\n error: %s\n", str);
exit(1);
}
void next_token(void)
{
token = buf[i++];
if (i > LENGTH)
error("The length of buffer is overflow");
}
void match(ch)
{
if (token == ch)
next_token();
else
error("syntax error");
}
int ctoi(char ch)
{
return ch - 48;
}
int isdigital(char d)
{
if ((ctoi(d) >= 0) && (ctoi(d) <= 9))
return 0;
else
return -1;
}
int factor(void)
{
int tmp;
if (token == '(') {
match('(');
printf("%c", '(');
tmp = expr();
match(')');
printf("%c", ')');
return tmp;
} else if (isdigital(token) == 0) {
printf("%c", token);
tmp = token;
next_token();
return ctoi(tmp);
} else
error("lexical error");
}
int term(void)
{
int tmp;
tmp = factor();
while (1) {
if (token == '*' ) {
match('*');
printf("%c", '*');
tmp = tmp * factor();
} else if (token == '/' ) {
match('/');
printf("%c", '/');
tmp = tmp / factor();
} else
break;
}
return tmp;
}
int expr(void)
{
int tmp;
tmp = term();
while (1) {
if (token == '+' ) {
match('+');
printf("%c", '+');
tmp = tmp + term();
} else if (token == '-' ) {
match('-');
printf("%c", '-');
tmp = tmp - term();
} else
break;
}
return tmp;
}
int main(void)
{
int tmp;
while(1) {
memset(buf, 0, LENGTH);
i = 0;
printf("plese input the expression:\n");
gets(buf);
if (strcmp(buf, "quit") == 0)
break;
printf("start to parse\n");
next_token();
tmp = expr();
printf(" = %d", tmp);
printf("\n");
}
return 0;
} |
[ 本帖最后由 rocenting 于 2009-3-22 00:49 编辑 ] |
|