tiny C 语法(对编译原理bnf熟悉的进)

Kevin_qing 2005-06-20 11:34:42
目前做一tinyC编译器,不支持函数定义,但支持函数call,数学/比较/逻辑运算if-else/goto/switch语法

switch语法为

switch(exp){
1:
.....
2:
........
}




BNF如下:

%token ID IF ELSE SWITCH GOTO RETURN NUMBER STRING MAIN
%token ADD_OP MUL_OP ASSIGN_OP CMP_OP LOGIC_OP1 LOGIC_OP2
%token LPAREN RPAREN LBRACE RBRACE COLON COMMA SEMI

%%
PROG
: MAIN compound_statement
;

compound_statement
: LBRACE statement_sequence RBRACE
;

statement_sequence
: labled_statement
| statement_sequence labled_statement
;

LABLE : ID COLON
;

labled_statement
: statement
| LABLE statement
;
statement
: EXPR SEMI
| SEMI
| GOTO ID SEMI
| RETURN SEMI
| IF LPAREN EXPR RPAREN statement
| IF LPAREN EXPR RPAREN statement ELSE statement
| SWITCH LPAREN EXPR RPAREN LBRACE CASES RBRACE
| compound_statement
;

CASE : NUMBERS COLON statement
;

CASES : CASE
| CASES CASE
;

NUMBERS : ADD_OP NUMBER
| NUMBER
;

STRINGS : STRING
| STRINGS STRING
;

PAM_LIST
: EXPR
| PAM_LIST COMMA EXPR
;

PRI_EXPR
: ID
| NUMBERS
| STRINGS
| LPAREN EXPR RPAREN
;

POST_EXPR
: PRI_EXPR
| ID LPAREN RPAREN
| ID LPAREN PAM_LIST RPAREN
;

MUL_EXPR
: POST_EXPR
| MUL_EXPR MUL_OP POST_EXPR
;

ADD_EXPR
: MUL_EXPR
| ADD_EXPR ADD_OP MUL_EXPR
;

CMP_EXPR
: ADD_EXPR
| ADD_EXPR CMP_OP ADD_EXPR
;

LOGIC_EXPR
: CMP_EXPR
| LOGIC_EXPR LOGIC_OP2 CMP_EXPR
| LOGIC_OP1 CMP_EXPR
;

EXPR
: LOGIC_EXPR
| ID ASSIGN_OP EXPR
;

%%

帮忙看看bnf还有没有问题
...全文
365 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
Knuthocean 2005-06-22
  • 打赏
  • 举报
回复
哎,结了!
Knuthocean 2005-06-22
  • 打赏
  • 举报
回复
你的
POST_EXPR
: PRI_EXPR
| ID LPAREN RPAREN
| ID LPAREN PAM_LIST RPAREN
;

那这里面的ID是不是一定为call呢?那还不如直结写成CALL
Kevin_qing 2005-06-22
  • 打赏
  • 举报
回复
SMT_SEQ就是statement_sequence的简写
Knuthocean 2005-06-22
  • 打赏
  • 举报
回复
SMT_SEQ这个是你的方法的非终结符吗?这怎么好像没有看到呀!
Kevin_qing 2005-06-22
  • 打赏
  • 举报
回复
函数call

LPAREN就是(

Knuthocean 2005-06-22
  • 打赏
  • 举报
回复
你的
POST_EXPR
: PRI_EXPR
| ID LPAREN RPAREN
| ID LPAREN PAM_LIST RPAREN
;
是什么意思?
Knuthocean 2005-06-22
  • 打赏
  • 举报
回复
Sorry!应该是改为
SWITCH LPAREN EXPR RPAREN LBRACE "case" CASES RBRACE
Kevin_qing 2005-06-22
  • 打赏
  • 举报
回复
我的意思是修改
CASE -> NUMBER COLON SMT_SEQ
后有状态冲突


已通过修改bnf为
CASE -> NUMBER COLON
CASES -> CASE SMT_SEQ |CASES CASE SMT_SEQ
解决问题
Knuthocean 2005-06-22
  • 打赏
  • 举报
回复
SWITCH LPAREN EXPR RPAREN LBRACE CASES RBRACE
把这个改为
SWITCH LPAREN EXPR RPAREN LBRACE "case" RBRACE(只是表达意思,不符合YACC)
是不是你想要的?
Knuthocean 2005-06-22
  • 打赏
  • 举报
回复
statement_sequence
: labled_statement
| statement_sequence labled_statement
;
你对这个statement_sequence把标号也考虑进来了,导致CASE语句不好定义多个语句的情况出现!
可修改为statement_sequence->statement | statement_sequence statement,再加上一个
labled_statement_sequence->labled_statement_sequence labled_statement | labeld_statement
解决上述的问题便只要把
CASE: NUMBERS COLON statement 改成CASE: NUMBERS COLON statement_sequence
像你这样把有label的statement和没有一般的statement混在一块我学得可读性很差,而且后面会遇到其它的麻烦


Knuthocean 2005-06-22
  • 打赏
  • 举报
回复
CASE: NUMBERS COLON statement
;
而你的statement要么定义成单个语句,要么定义成加上{}的复合语句,当然出错
Kevin_qing 2005-06-22
  • 打赏
  • 举报
回复
id不是call
id是任意标志符

比如
main(){

say("现在时间%d:%02d:%02d",tm_get_Hour(),tm_get_Min(),tm_get_Sec());

}
Kevin_qing 2005-06-21
  • 打赏
  • 举报
回复
目前
switch的case后必须跟单句或复合语句,而不能跟语句序列

switch(3){
1: say("ok");
2: {
say ("ok");
say ("......");
}
3: say("ok");
say("error");//此处编译会出错...
}


是否可以通过修改bnf支持 3.
Kevin_qing 2005-06-21
  • 打赏
  • 举报
回复
目前遇到的问题是
case 语句因为没有先行符号"case"
如果
CASE -> NUMBER ':' SMT_SEQ

在 SMT_SEQ 后遇到NUMBER会出现冲突
SMT_SEQ . SMT 或 SMT_SEQ . CASE

是否有办法解决此问题?


在词法分析时限定 NUMBER':'为 CASE,将CASE作为终结符可解决此问题
brianlu 2005-06-20
  • 打赏
  • 举报
回复
up
Kevin_qing 2005-06-20
  • 打赏
  • 举报
回复
悬挂ELSE的问题没有用bnf解决,而是在分析表里面直接使用正确的状态

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧