Chinaunix

标题: 初学者,请教各位先辈,关于语法分析的一些问题。 [打印本页]

作者: rocenting    时间: 2009-03-21 21:28
标题: 初学者,请教各位先辈,关于语法分析的一些问题。
编译领域初学者,看了几天书,并参考了一些资料,花了两个多小时做了一个简单的计算器,支持(),不支持空格,计算对象不大于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)
{
&nbsp;&nbsp;&nbsp;&nbsp;printf("\n error: %s\n", str);
&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
}

void next_token(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;token = buf[i++];
&nbsp;&nbsp;&nbsp;&nbsp;if (i > LENGTH)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error("The length of buffer is overflow");&nbsp;&nbsp;&nbsp;&nbsp;
}

void match(ch)
{
&nbsp;&nbsp;&nbsp;&nbsp;if (token == ch)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_token();
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error("syntax error");
}

int ctoi(char ch)
{
&nbsp;&nbsp;&nbsp;&nbsp;return ch - 48;
}

int isdigital(char d)
{
&nbsp;&nbsp;&nbsp;&nbsp;if ((ctoi(d) >= 0) && (ctoi(d) <= 9))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
}
int factor(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;int tmp;
&nbsp;&nbsp;&nbsp;&nbsp;if (token == '(') {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;match('(');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%c", '(');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp = expr();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;match(')');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%c", ')');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return tmp;
&nbsp;&nbsp;&nbsp;&nbsp;} else if (isdigital(token) == 0) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%c", token);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp = token;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_token();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ctoi(tmp);
&nbsp;&nbsp;&nbsp;&nbsp;} else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error("lexical error");
}

int term(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;int tmp;
&nbsp;&nbsp;&nbsp;&nbsp;tmp = factor();
&nbsp;&nbsp;&nbsp;&nbsp;while (1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (token == '*' ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;match('*');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%c", '*');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp = tmp * factor();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else if (token == '/' ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;match('/');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%c", '/');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp = tmp / factor();&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return tmp;
}
&nbsp;
int expr(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;int tmp;
&nbsp;&nbsp;&nbsp;&nbsp;tmp = term();
&nbsp;&nbsp;&nbsp;&nbsp;while (1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (token == '+' ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;match('+');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%c", '+');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp = tmp + term();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else if (token == '-' ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;match('-');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%c", '-');
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp = tmp - term();&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return tmp;
}

int main(void)
{
&nbsp;&nbsp;&nbsp;&nbsp;int tmp;
&nbsp;&nbsp;&nbsp;&nbsp;while(1) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(buf, 0, LENGTH);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i = 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("plese input the expression:\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gets(buf);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (strcmp(buf, "quit") == 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("start to parse\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next_token();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tmp = expr();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(" = %d", tmp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("\n");
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}


[ 本帖最后由 rocenting 于 2009-3-22 00:49 编辑 ]
作者: mik    时间: 2009-03-21 23:16
自已做些调试和测试吧
作者: rocenting    时间: 2009-03-21 23:59
原帖由 mik 于 2009-3-21 23:16 发表
自已做些调试和测试吧



程序本身没有问题的,但感觉自己就是没有完全掌握,所以想找人指点一下呵呵。

mik是珠海的啊,好像记忆中建荣要做自己的编译器的,用于一个单片机,莫非。。。。
作者: rocenting    时间: 2009-03-22 00:46
研究了一下,终于解决了,感觉EBNF才能直接对应流程图。
作者: mik    时间: 2009-03-22 00:47
原帖由 rocenting 于 2009-3-21 23:59 发表



程序本身没有问题的,但感觉自己就是没有完全掌握,所以想找人指点一下呵呵。

mik是珠海的啊,好像记忆中建荣要做自己的编译器的,用于一个单片机,莫非。。。。


建荣是啥公司?

给介绍介绍吧
作者: rocenting    时间: 2009-03-22 00:52
原帖由 mik 于 2009-3-22 00:47 发表


建荣是啥公司?

给介绍介绍吧



IC公司。

我以前同事在那里做IC,所以听说了一些。

以前在珠海面试过一些人也提到那个公司也搞编译器的。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2