千月星跡
アイをも求めて彷徨っている孤独なヒーロー
登录
注册
全站
当前博客
空间
博客
好友
相册
留言
last_impression
ID:Last_Impression
共
11551
次访问,排名
9404(1)
好友
0
人,关注者
3
人
Last_Impression的文章
原创 52 篇
翻译 3 篇
转载 76 篇
评论 1 篇
最近评论
mohroq:
wow gold
,
文章分类
C++
(RSS)
C++设计模式(QT)
(RSS)
C语言
(RSS)
Qt
(RSS)
Ruby
(RSS)
VB语言
(RSS)
VC++多线程应用
(RSS)
YACC
(RSS)
测试&&品质
(RSS)
设计模式
(RSS)
孙鑫VC++
(RSS)
系统分析师-论文
(RSS)
收藏
相册
存档
2008年08月(2)
2008年07月(5)
2008年06月(1)
2008年05月(31)
2008年04月(11)
2008年03月(7)
2008年02月(8)
2008年01月(18)
2007年12月(12)
2007年10月(7)
2007年09月(8)
2007年08月(21)
订阅我的博客
解释器的代码....
收藏
新一篇: zheng zhe biao da shi
|
旧一篇: 的功能扩张....
这个是书上的例子,
%{
#include <stdio.h>
#include <stdlib.h>
#define STRSIZE
64
#include
"
y.tab.h
"
#include
"
intall.h
"
extern void lexerror()
;
int strcnt
=
0
;
char string
[
STRSIZE + 1
]
=
{
0
}
;
%}
%start STR1 COMM
%%
<INITIAL>
"
+
"
{return(ADDOP)
;
}
<INITIAL>
"
-
"
{return(SUBOP)
;
}
<INITIAL>
"
*
"
{return(MULOP)
;
}
<INITIAL>
"
/
"
{return(DIVOP)
;
}
<INITIAL>
"
=
"
{return(ASGNOP)
;
}
<INITIAL>
"
==
"
{return(EQOP)
;
}
<INITIAL>
"
>
"
{return(GTOP)
;
}
<INITIAL>
"
>=
"
{return(GEOP)
;
}
<INITIAL>
"
<
"
{return(LSOP)
;
}
<INITIAL>
"
<=
"
{return(LEOP)
;
}
<INITIAL>
"
!=
"
{return(NTOP)
;
}
<INITIAL>
"
{
"
{return(LC)
;
}
<INITIAL>
"
}
"
{return(RC)
;
}
<INITIAL>
"
(
"
{return(LP)
;
}
<INITIAL>
"
)
"
{return(RP)
;
}
<INITIAL>
"
;
"
{return(SM)
;
}
<INITIAL>
"
,
"
{return(CM)
;
}
<INITIAL>
"
{
strcnt = 0;
BEGIN STR1;
}
<INITIAL>
"
/*
"
BEGIN COMM;
<INITIAL>if {return(IF);}
<INITIAL>else {return(ELSE);}
<INITIAL>while {return(WHILE);}
<INITIAL>put {return(PUT);}
<INITIAL>get {return(GET);}
<INITIAL>[a-z] {
yylval.idno = yytext[0] -'a';
return(IDENT);
}
<INITIAL>[0-9]+ {
yylval.num = atoi((char*)yytext);
return(NUMBER);
}
<INITIAL>[ ] ;
<INITIAL>[a-z0-9]+ {lexerror(
"
word invalid
"
);}
<INITIAL>. {lexerror(
"
character invalid
"
);}
<STR1>
"
{
if (strcnt>
=
STRSIZE)lexerror(
"
string too long
"
)
;
string
[
strcnt
]
=
'
0
'
;
yylval.addr
=
pool(string)
;
BEGIN INITIAL
;
return(STRING)
;
}
<STR1>\
"
{
if (strcnt < STRSIZE)
string[strcnt++] = '
"
'
;
}
<STR1>\n {
if (strcnt < STRSIZE)
string
[
strcnt++
]
=
' '
;
}
<STR1> {
lexerror(
"
string not closed
"
)
;
string
[
strcnt
]
=
'
0
'
;
yylval.addr
=
pool(string)
;
BEGIN INITIAL
;
return(STRING)
;
}
<STR1>. {
if (strcnt <STRSIZE)string
[
strcnt++
]
=
yytext
[
0
]
;
}
<COMM>
"
*/
"
{
BEGIN INITIAL
;
}
<COMM>
;
<COMM>.
;
%%
void lexerror(char *s)
{
extern int yynerrs
,
yylineno
;
++yynerrs
;
fprintf(stderr
,
"
%d:%s
"
,
yylineno
,
s)
;
}
这个文件应该多留心 字符串和注释的写法
%
...
{
#include
<
stdio.h
>
#include
"
intall.h
"
#define
ID 100
#define
NUM 101
#define
STR 102
#define
NODESIZE 100
int
nodecnt
=
0
;
struct
node
...
{
int
ntype;
int
nvalue;
struct
node
*
left;
struct
node
*
right;
}
nodearea[NODESIZE]
=
...
{
0
}
;
%
}
%
union
...
{
int
idno;
int
num;
int
addr;
int
label;
struct
node
*
nodep;
}
%
token
<
idno
>
IDENT
%
token
<
num
>
NUMBER
%
token
<
addr
>
STRING
%
token IF ELSE WHILE GET PUT
%
token LP RP
%
token LC RC
%
token CM SM
%
token ASGNOP
%
token EQOP GTOP GEOP LSOP LEOP NTOP
%
left ADDOP SUBOP
%
left MULOP DIVOP
%
right MINUS
%
type
<
label
>
if
.prefix
while
.prefix
%
type
<
nodep
>
expr cond
%%
s :stmt.list
;
stmt.list
:
/**/
/*
empty
*/
|
stmt.list stmt
;
stmt :IDENT ASGNOP expr SM
...
{
genexpr($
3
);
clearnode();
gencode(OP_POP, $
1
);
}
|
if
.prefix stmt
...
{gencode(OP_LBL,$
1
);}
|
if
.prefix stmt ELSE
...
{
gencode(OP_JMP, $
<
label
>
$
=
newlbl());
gencode(OP_LBL,$
1
);
}
stmt
...
{gencode(OP_LBL, $
<
label
>
$);}
|
while
.prefix
...
{
gencode(OP_JPF, $
<
label
>
4
=
newlbl());
}
stmt
...
{
gencode(OP_JMP, $
1
);
gencode(OP_LBL, $
<
label
>
2
);
}
|
PUT LP put.list RP SM
|
GET LP IDENT RP SM
...
{gencode(OP_GET,$
3
);}
|
LC stmt.list RC
|
SM
|
error SM
...
{
//
可以使用一?机制来?制解析器相信??已?被完全修?了
yyerrok;
clearnode();
}
|
error RC
...
{
yyerrok;
clearnode();
}
;
if
.prefix
:IF LP cond RP
...
{
genexpr($
3
);
clearnode();
gencode(OP_JPF,$$
=
newlbl());
}
;
while
.prefix
:WHILE LP cond RP
...
{
gencode(OP_LBL,$$
=
newlbl());
genexpr($
3
);
clearnode();
}
;
put.list
:id.num.or.str
|
put.list CM id.num.or.str
;
id.num.or.str
:IDENT
...
{gencode(OP_PUTI, $
1
);}
|
NUMBER
...
{gencode(OP_PUTN, $
1
);}
|
STRING
...
{gencode(OP_PUTS, $
1
);}
;
cond :expr EQOP expr
...
{$$
=
makeexpr(EQ, $
1
, $
3
);}
|
expr GTOP expr
...
{$$
=
makeexpr(GT, $
1
, $
3
);}
|
expr GEOP expr
...
{$$
=
makeexpr(GE, $
1
, $
3
);}
|
expr LSOP expr
...
{$$
=
makeexpr(LS, $
1
, $
3
);}
|
expr LEOP expr
...
{$$
=
makeexpr(LE, $
1
, $
3
);}
|
expr NTOP expr
...
{$$
=
makeexpr(NT, $
1
, $
3
);}
;
expr :expr ADDOP expr
...
{$$
=
makeexpr(ADD, $
1
, $
3
);}
|
expr SUBOP expr
...
{$$
=
makeexpr(SUB, $
1
, $
3
);}
|
expr MULOP expr
...
{$$
=
makeexpr(MUL, $
1
, $
3
);}
|
expr DIVOP expr
...
{$$
=
makeexpr(DIV, $
1
, $
3
);}
|
SUBOP expr
%
prec MINUS
...
{$$
=
makeexpr(MIN, $
2
,
0
);}
|
LP expr RP
...
{$$
=
$
2
;}
|
IDENT
...
{$$
=
makenode(ID, $
1
);}
|
NUMBER
...
{$$
=
makenode(NUM, $
1
);}
;
%%
int
yyerror(
char
*
str)
...
{
printf(
"
%s
"
, str);
}
void
clearnode()
...
{
nodecnt
=
0
;
}
struct
node
*
getnode()
...
{
if
(nodecnt
>
NODESIZE)
...
{
fatal(
"
nodearea overflow
"
);
}
return
(
&
nodearea[nodecnt
++
]);
}
struct
node
*
makenode(
int
type ,
int
value)
...
{
struct
node
*
p;
p
=
getnode();
p
->
ntype
=
type;
p
->
nvalue
=
value;
p
->
left
=
NULL;
p
->
right
=
NULL;
return
(p);
}
struct
node
*
makeexpr(
int
type,
struct
node
*
left,
struct
node
*
right)
...
{
struct
node
*
p;
p
=
makenode(type ,
0
);
p
->
left
=
left;
p
->
right
=
right;
return
(p);
}
/**/
/*
式のとリーから中間コードを生成する
*/
void
genexpr(
struct
node
*
p)
...
{
if
(p
==
NULL)
...
{
return
;
}
if
(p
->
left)
...
{
&nbs