编译原理词法分析程序和语法分析程序
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)各种单词符号对应的种别编码
(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();
}
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();
}
相关文章推荐
- 编译原理之算符优先分析语法程序
- 1217 实验四 递归下降语法分析程序设计
- 1225-实验四-递归下降语法分析程序设计
- 递归下降语法分析程序设计
- 编译中的基于算符优先分析程序的语法制导翻译
- 1223 递归下降语法分析程序设计
- LR(1)表驱动语法分析程序
- 递归下降语法分析程序设计
- 12.16_实验四 递归下降语法分析程序设计
- 语法分析程序
- 1230递归下降语法分析程序设计
- 编译原理语法分析对循环语句和条件判断语句编写词法分析编译程序,只能通过一遍扫描完成
- java语法,是理解、分析和解决任何java程序、框架、工程的万能切入点
- 递归下降语法分析程序设计
- 1217 实验四 递归下降语法分析程序设计
- 1217 实验四 递归下降语法分析程序设计
- C++:基于LL(1)方法的语法分析程序-1
- 编写语法分析程序
- 关于Basic程序解释器及编译原理的简单化(1)---Basic器的语法分析及主要代码
- 编译原理 实验3 递归下降语法分析程序设计