您的位置:首页 > 编程语言

编译原理词法分析程序和语法分析程序

2017-12-29 11:29 155 查看
(1)待分析的简单语言的词法

1) 关键字

begin if thenwhile do end

2) 运算符和界符

:= + - * / <<= > >= <> = ; ( ) #

3) 其他单词是标识符(ID)和整形常数(NUM),通过以下正规式定义:

ID=letter(letter|digit)*

NUM=digitdigit*

4) 空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。

 

(2)各种单词符号对应的种别编码

单词符号
种别码
单词符号
种别码
begin
1
:
17
if
2
:=
18
then
3

20
while
4
<> 
21
do
5
<=
22
end
6

23
letter(letter|digit)*
10
>=
24
digitdigit*
11
=
25
+
13
;
26
-
14
(
27
*
15
)
28
/
16
#
0
 

(3)词法分析程序的功能

输入:所给文法的源程序字符串

输出:二元组(syn,token或sum)构成的序列。

syn为单词种别码;

token为存放的单词自身字符串;

sum为整形常数。

例如:对源程序begin x:=9;ifx>0 then x:=2*x+1/3;end# 经词法分析后输出如下序列:(1,begin)(10,’x’) (18,:=) (11,9) (26,;) (2,if)……

代码如下:

#include "stdafx.h"

#include <string.h>

int main()

{
int p = 0;
int q;
int syn;
printf("please input string : \n");
char ch[100];
gets_s(ch);
char *key[6] = { "begin","if","then","while","do","end" };
/*do {
ch[p++] = getchar();
} while (getchar() != '#');*/
p = 0;
do {
char token[100] = {};
q = 0;
while (ch[p] == ' ') {
p++;
}
if ((ch[p] >= 'a'&&ch[p] <= 'z') || (ch[p] >= 'A'&&ch[p] <= 'Z')) {
token[q++] = ch[p];
p++;
while ((ch[p] >= '0'&&ch[p] <= '9') || (ch[p] >= 'a'&&ch[p] <= 'z') || (ch[p] >= 'A'&&ch[p] <= 'Z')) {
token[q++] = ch[p++];
}
syn = 10;
token[q] = '\0';
for (int n = 0; n < 6; n++) { //将识别出来的字符和已定义的标示符作比较, 
if (strcmp(token, key
) == 0)
{
syn = n + 1;
break;
}
}
}
else if (ch[p] >= '0'&&ch[p] <= '9') {
token[q++] = ch[p];
p++;
while (ch[p] >= '0'&&ch[p] <= '9') {
token[q++] = ch[p++];
}
syn = 11;
}
else switch (ch[p]) {
case'<':
token[q++] = ch[p++];
if (ch[p] == '>')
{
syn = 21;
token[q++] = ch[p++];
}
else if (ch[p] == '=')
{
syn = 22;
token[q++] = ch[p++];
}
else
{
syn = 23;
}
break;
case'>':
token[q++] = ch[p++];
if (ch[p] == '>')
{
syn = 24;
token[q++] = ch[p++];
}
else
{
syn = 20;
}
break;
case':':
token[q++] = ch[p++];
if (ch[p] == '=')
{
syn = 18;
token[q++] = ch[p++];
}
else
{
syn = 17;
}
break;
case'*':syn = 13; token[q++] = ch[p++]; break;
case'/':syn = 14; token[q++] = ch[p++]; break;
case'+':syn = 15; token[q++] = ch[p++]; break;
case'-':syn = 16; token[q] = ch[p]; break;
case'=':syn = 25; token[q++] = ch[p++]; break;
case';':syn = 26; token[q++] = ch[p++]; break;
case'(':syn = 27; token[q++] = ch[p++]; break;
case')':syn = 28; token[q++] = ch[p++]; break;
case'#':syn = 0; token[q++] = ch[p++]; break;
case'\n':syn = -2; break;
default: syn = -1; break;
}
switch (syn)
{
case -1:
printf("error\n");
break;
default:
printf("(%d,%s)\n", syn, token);
}
} while (syn > 0);

}

(1)待分析的简单语言的词法同上面表格

(2)待分析的简单语言的语法

用扩充的BNF表示如下:

1)<程序>::=begin<语句串>end

2) <语句串>::=<语句>{;<语句>}

3) <语句>::=<赋值语句>

4) <赋值语句>::=ID:=<表达式>

5) <表达式>::=<项>{+<项>|-<项>}

6) <项>::=<因子>{*<因子>|/<因子>}

7) <因子>::=ID|NUM|(<表达式>)

(3)语法分析程序的功能

输入单词串以”#”结束,如果是文法正确的句子,输出成功信息;否则输出错误信息。

例如:

输入   begin a:=9; x:=2 * 3; b:=a+ x end #

输出   success

输入   x:=a + b * c end #

输出   error

代码如下:

// 语法分析程序.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include "string.h"

int p = 0;

int q;

int syn;

char ch[100];

int kk = 0;

char *key[6] = { "begin","if","then","while","do","end" };

void scaner();

void yucu();

void statement();

void expression();

void term();

void factor();

void scaner() {
char token[100] = {};
q = 0;
while (ch[p] == ' ') {
p++;
}
if ((ch[p] >= 'a'&&ch[p] <= 'z') || (ch[p] >= 'A'&&ch[p] <= 'Z')) {
token[q++] = ch[p];
p++;
while ((ch[p] >= '0'&&ch[p] <= '9') || (ch[p] >= 'a'&&ch[p] <= 'z') || (ch[p] >= 'A'&&ch[p] <= 'Z')) {
token[q++] = ch[p++];
}
syn = 10;
token[q] = '\0';
for (int n = 0; n < 6; n++) { //将识别出来的字符和已定义的标示符作比较, 
if (strcmp(token, key
) == 0)
{
syn = n + 1;
break;
}
}
}
else if (ch[p] >= '0'&&ch[p] <= '9') {
token[q++] = ch[p];
p++;
while (ch[p] >= '0'&&ch[p] <= '9') {
token[q++] = ch[p++];
}
syn = 11;
}
else switch (ch[p]) {
case'<':
token[q++] = ch[p++];
if (ch[p] == '>')
{
syn = 21;
token[q++] = ch[p++];
}
else if (ch[p] == '=')
{
syn = 22;
token[q++] = ch[p++];
}
else
{
syn = 23;
}
break;
case'>':
token[q++] = ch[p++];
if (ch[p] == '>')
{
syn = 24;
token[q++] = ch[p++];
}
else
{
syn = 20;
}
break;
case':':
token[q++] = ch[p++];
if (ch[p] == '=')
{
syn = 18;
token[q++] = ch[p++];
}
else
{
syn = 17;
}
break;
case'*':syn = 13; token[q++] = ch[p++]; break;
case'/':syn = 14; token[q++] = ch[p++]; break;
case'+':syn = 15; token[q++] = ch[p++]; break;
case'-':syn = 16; token[q] = ch[p]; break;
case'=':syn = 25; token[q++] = ch[p++]; break;
case';':syn = 26; token[q++] = ch[p++]; break;
case'(':syn = 27; token[q++] = ch[p++]; break;
case')':syn = 28; token[q++] = ch[p++]; break;
case'#':syn = 0; token[q++] = ch[p++]; break;
case'\n':syn = -2; break;
default: syn = -1; break;
}
printf("%s", token);

}

/*1)<程序>:: = begin<语句串>end

2) <语句串>:: = <语句>{ ;<语句> }

3) <语句>:: = <赋值语句>

4) <赋值语句>:: = ID: = <表达式>

5) <表达式>:: = <项>{ +<项> | -<项> }

6) <项>:: = <因子>{ *<因子> | / <因子> }

7) <因子>:: = ID | NUM | (<表达式>)*/

void yucu() //语句串分析函数 <语句串>:: = <语句>{ ;<语句> }

{
scaner();
if (syn == 1) //begin
{
statement();  
//printf("%d", syn);
while (syn == 26) {
statement();
//printf("1\n");
}
if (syn == 6)
{
scaner();
if (syn == 0)
printf("success!\n");
else
printf("end 后出错");
}
else { 
printf("the string haven't got a'end'!\n");
kk = 1;
}
}
else {
printf("haven't got a 'begin'!\n");
kk = 1;
}

}

void statement()  //语句分析函数  <语句>:: = <赋值语句>  <赋值语句>:: = ID: = <表达式>

{
scaner();
if (syn == 10) //变量
{
scaner();        /*读下一个单词符号*/
if (syn == 18) //:= 读表达式
{
scaner();      /*读下一个单词符号*/
expression();     
}
else {
printf("the sing ':=' is wrong!\n");
kk = 1;
}
}
else {
printf("wrong sentence!\n");
kk = 1;
}
return;

}

void expression() //表达式 <表达式>:: = <项>{ +<项> | -<项> }

{
term();
while ((syn == 13) || (syn == 14)) //+ -
{
scaner();            /*读下一个单词符号*/
term();               
}
return;

}

void term() //项  <项>:: = <因子>{ *<因子> | / <因子> }

{
factor();
while ((syn == 15) || (syn == 16)) //* /
{
scaner();            /*读下一个单词符号*/
factor();       
}
return;

}

void factor() //因子 <因子>:: = ID | NUM | (<表达式>)*/

{
if ((syn == 10) || (syn == 11))  //num or letter
scaner();
else if (syn == 27) //(
{
scaner();          /*读下一个单词符号*/
expression();        /*调用函数statement();*/
if (syn == 28) //)
scaner();          /*读下一个单词符号*/
else {
printf("the error on '('\n");
kk = 1;
}
}
else {
printf("the expression error!\n");
kk = 1;
}
return;

}

int main()

{
printf("please input string : \n");
gets_s(ch);
/*do {
ch[p++] = getchar();
} while (getchar() != '#');*/
yucu();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息