#include iostream
创新互联坚信:善待客户,将会成为终身客户。我们能坚持多年,是因为我们一直可值得信赖。我们从不忽悠初访客户,我们用心做好本职工作,不忘初心,方得始终。10年网站建设经验创新互联是成都老牌网站营销服务商,为您提供网站建设、做网站、网站设计、HTML5、网站制作、品牌网站建设、微信小程序定制开发服务,给众多知名企业提供过好品质的建站服务。
#include string
using namespace std;
string key[6] = {"begin", "if", "then", "while", "do", "end"};
//关键字
bool isKey( string str, int syn) //判断是否为关键字,若是传回相
应关键码的种别名
{
int i;
for(i=0; i6; i++)
{
if(str == key[i])
{
syn = i + 1;
return true;
}
}
return false;
}
bool isLetter(char c) //是否为字母
{
if((c = 'A' c = 'Z') || (c = 'a' c = 'z'))
return true;
else
return false;
}
bool isDigit(char c) //是否为数字
{
if(c = '0' c = '9')
return true;
else
return false;
}
void analyse(FILE *fileP)
{
int n;
char c;
string str = "";
while((c = fgetc(fileP)) != EOF)
{
if(c == ' ' || c == '\n' || c == '\t')
continue;
else if(isDigit(c)) //数字
{
while(isDigit(c))
{
str += c;
c = fgetc(fileP);
}
fseek(fileP, -1, SEEK_CUR);
cout "(11, " str ")" endl;
str = "";
}
else if(isLetter(c)) //字母开头的
{
while(isDigit(c) || isLetter(c))
{
str += c;
c = fgetc(fileP);
}
fseek(fileP, -1, SEEK_CUR);
if(isKey(str, n))
cout "(" n ", " str ")" endl; //关键码
else
cout "(10, " "\'" str "\'" ")" endl; //标志符
str = "";
}
else //操作符等
{
switch(c)
{
case '+':
cout "(13, +)" endl;
break;
case '-':
cout "(14, -)" endl;
break;
case '*':
cout "(15, *)" endl;
break;
case '/':
cout "(16, /)" endl;
break;
case ':':
{
if(c=fgetc(fileP) == '=')
cout "(18, :=)" endl;
else
{
cout "(17, :)" endl;
fseek(fileP, -1, SEEK_CUR);
}
break;
}
case '':
{
c=fgetc(fileP);
if(c == '=')
cout "(22, =)" endl;
else if(c == '')
cout "(21, )" endl;
else
{
cout "(20, )" endl;
fseek(fileP, -1, SEEK_CUR);
}
break;
}
case '':
{
c=fgetc(fileP);
if(c == '=')
cout "(24, =)" endl;
else
{
cout "(23, )" endl;
fseek(fileP, -1, SEEK_CUR);
}
break;
}
case '=':
cout "(25, =)" endl;
break;
case ';':
cout "(26, ;)" endl;
break;
case '(':
cout "(27, ()" endl;
break;
case ')':
cout "(28, ))" endl;
break;
case '#':
cout "(0, #)" endl;
break;
}
}
}
}
int main()
{
FILE *fileP;
fileP = fopen("test.txt", "r");
cout "------词法分析如下------" endl;
analyse(fileP);
return 0;
}
简而言之就是先画一个状态图,然后根据图来编码就行
一个简单的xml的词法分析器供参考
#include
stdio.h
#include
stdlib.h
#include
string.h
typedef
struct
{
char
*p;
int
len;
}
xml_Text;
typedef
enum
{
xml_tt_U,
/*
Unknow
*/
xml_tt_H,
/*
Head
?xxx?*/
xml_tt_E,
/*
End
/xxx
*/
xml_tt_B,
/*
Begin
xxx
*/
xml_tt_BE,
/*
Begin
End
xxx/
*/
xml_tt_T
/*
Text
xxx
*/
}
xml_TokenType;
typedef
struct
{
xml_Text
text;
xml_TokenType
type;
}
xml_Token;
int
xml_initText(xml_Text
*pText,
char
*s)
{
pText-p
=
s;
pText-len
=
strlen(s);
return
0;
}
int
xml_initToken(xml_Token
*pToken,
xml_Text
*pText)
{
pToken-text.p
=
pText-p;
pToken-text.len
=
0;
pToken-type
=
xml_tt_U;
return
0;
}
int
xml_print(xml_Text
*pText)
{
int
i;
for
(i
=
0;
i
pText-len;
i++)
{
putchar(pText-p[i]);
}
return
0;
}
int
xml_println(xml_Text
*pText)
{
xml_print(pText);
putchar('\n');
return
0;
}
int
xml_getToken(xml_Text
*pText,
xml_Token
*pToken)
{
char
*start
=
pToken-text.p
+
pToken-text.len;
char
*p
=
start;
char
*end
=
pText-p
+
pText-len;
int
state
=
0;
pToken-text.p
=
p;
pToken-type
=
xml_tt_U;
for
(;
p
end;
p++)
{
switch(state)
{
case
0:
switch(*p)
{
case
'':
state
=
1;
break;
default:
state
=
7;
break;
}
break;
case
1:
switch(*p)
{
case
'?':
state
=
2;
break;
case
'/':
state
=
4;
break;
default:
state
=
5;
break;
}
break;
case
2:
switch(*p)
{
case
'?':
state
=
3;
break;
default:
state
=
2;
break;
}
break;
case
3:
switch(*p)
{
case
'':
pToken-text.len
=
p
-
start
+
1;
pToken-type
=
xml_tt_H;
return
1;
default:
state
=
-1;
break;
}
break;
case
4:
switch(*p)
{
case
'':
pToken-text.len
=
p
-
start
+
1;
pToken-type
=
xml_tt_E;
return
1;
default:
state
=
4;
break;
}
break;
case
5:
switch(*p)
{
case
'':
pToken-text.len
=
p
-
start
+
1;
pToken-type
=
xml_tt_B;
return
1;
case
'/':
state
=
6;
break;
default:
state
=
5;
break;
}
break;
case
6:
switch(*p)
{
case
'':
pToken-text.len
=
p
-
start
+
1;
pToken-type
=
xml_tt_BE;
return
1;
default:
state
=
-1;
break;
}
break;
case
7:
switch(*p)
{
case
'':
p--;
pToken-text.len
=
p
-
start
+
1;
pToken-type
=
xml_tt_T;
return
1;
default:
state
=
7;
break;
}
break;
default:
pToken-text.len
=
p
-
start
+
1;
pToken-type
=
xml_tt_T;
return
1;
}
}
return
0;
}
int
main()
{
int
ret
=
0;
xml_Text
xml;
xml_initText(xml,
"?xml?root
ss
hahahoho/haha/root");
xml_Token
token;
xml_initToken(token,
xml);
ret
=
xml_getToken(xml,
token);
printf("ret=%d;text=",ret);
xml_print(token.text);
printf(";type=%d;\n\n",
token.type);
ret
=
xml_getToken(xml,
token);
printf("ret=%d;text=",ret);
xml_print(token.text);
printf(";type=%d;\n\n",
token.type);
ret
=
xml_getToken(xml,
token);
printf("ret=%d;text=",ret);
xml_print(token.text);
printf(";type=%d;\n\n",
token.type);
ret
=
xml_getToken(xml,
token);
printf("ret=%d;text=",ret);
xml_print(token.text);
printf(";type=%d;\n\n",
token.type);
ret
=
xml_getToken(xml,
token);
printf("ret=%d;text=",ret);
xml_print(token.text);
printf(";type=%d;\n\n",
token.type);
ret
=
xml_getToken(xml,
token);
printf("ret=%d;text=",ret);
xml_print(token.text);
printf(";type=%d;\n\n",
token.type);
ret
=
xml_getToken(xml,
token);
printf("ret=%d;text=",ret);
xml_print(token.text);
printf(";type=%d;\n\n",
token.type);
return
0;
}
goto语句也称为无条件转移语句,其一般格式如下: goto 语句标号; 其中语句标号是按标识符规定书写的符号, 放在某一语句行的前面,标号后加冒号(:)。语句标号起标识语句的作用,与goto 语句配合使用。
如: label: i++;
loop: while(x7);
goto loop;
C语言不限制程序中使用标号的次数,但各标号不得重名。goto语句的语义是改变程序流向, 转去执行语句标号所标识的语句。
goto语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。
扩展资料:
go to在C语言中的应用:
统计从键盘输入一行字符的个数。
#includestdio.h
int n=0;
int main(void) {
printf("input a string: ");
loop: if (getchar()!='\n') {
n++;
goto loop;
}
printf("output: %d\n",n);
}
例如输入:abcdefghijklmnopqrstuvwxyz
然后回车Enter
输出:26
本例用if语句和goto语句构成循环结构。当输入字符不为'\n'时即执行n++进行计数。
然后转移至if语句循环执行,直至输入字符为'\n'才停止循环。
参考资料:百度百科-go to 语句