免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1992 | 回复: 5
打印 上一主题 下一主题

初学者,请教各位先辈,关于语法分析的一些问题。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 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 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-03-21 23:16 |只看该作者
自已做些调试和测试吧

论坛徽章:
0
3 [报告]
发表于 2009-03-21 23:59 |只看该作者
原帖由 mik 于 2009-3-21 23:16 发表
自已做些调试和测试吧



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

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

论坛徽章:
0
4 [报告]
发表于 2009-03-22 00:46 |只看该作者
研究了一下,终于解决了,感觉EBNF才能直接对应流程图。

论坛徽章:
0
5 [报告]
发表于 2009-03-22 00:47 |只看该作者
原帖由 rocenting 于 2009-3-21 23:59 发表



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

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


建荣是啥公司?

给介绍介绍吧

论坛徽章:
0
6 [报告]
发表于 2009-03-22 00:52 |只看该作者
原帖由 mik 于 2009-3-22 00:47 发表


建荣是啥公司?

给介绍介绍吧



IC公司。

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

以前在珠海面试过一些人也提到那个公司也搞编译器的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP