联系方式

  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-23:00
  • 微信:codinghelp

您当前位置:首页 >> Java编程Java编程

日期:2018-05-06 06:36


1 .PL/0  语言文 法的 的 EBNF

<程序>::=<分程序>.

<分程序> ::=[<常量说明>][<变量说明>][<过程说明>]<语句>

<常量说明> ::=CONST<常量定义>{,<常量定义>};

<常量定义> ::=<标识符>=<无符号整数>

<无符号整数> ::= <数字>{<数字>}

<变量说明> ::=VAR <标识符>{, <标识符>};

<标识符> ::=<字母>{<字母>|<数字>}

<过程说明> ::=<过程首部><分程序>{; <过程说明> };

<过程首部> ::=PROCEDURE <标识符>;

<语句> ::=<赋值语句>|<条件语句>|<当循环语句>|<过程调用语句>

|<复合语句>|<读语句><写语句>|<空>

<赋值语句> ::=<标识符>:=<表达式>

<复合语句> ::=BEGIN <语句> {;<语句> }END

<条件表达式> ::= <表达式> <关系运算符> <表达式> |ODD<表达式>

<表达式> ::= [+|-]<项>{<加法运算符> <项>}

<项> ::= <因子>{<乘法运算符> <因子>}

<因子> ::= <标识符>|<无符号整数>| ‘(’<表达式>‘)’

<加法运算符> ::= +|-

<乘法运算符> ::= *|/

<关系运算符> ::= =|#|<|<=|>|>=

<条件语句> ::= IF <条件表达式> THEN <语句>

《编译原理》实验指导书

上海大学 计算机学院 《编译原理》课程组 4 of 39

<过程调用语句> ::= CALL 标识符

<当循环语句> ::= WHILE <条件表达式> DO <语句>

<读语句> ::= READ‘(’<标识符>{,<标识符>}‘)’

<写语句> ::= WRITE‘(’<表达式>{,<表达式>}‘)’

<字母> ::= a|b|…|X|Y|Z

<数字> ::= 0|1|…|8|9

要求:改变输入方式,使得普通语句也能进行语法分析(a+15)*b 作为输

入。

就是将本来的

(lparen,( )

(ident, a)

(plus, + )

(number, 15)

(rparen,) )

(times, * )

(ident, b )

二元组形式的输入转化成正常表达式(a+15)*b形式的输入(通过文件读取信息)


#include<iostream>

#include<stack>

#include<string>

#include<fstream>

using namespace std;


static int rg = 1;

static int rg1 = 1;

static int rg2 = 1;

struct newsym

{

char restr[15];

};


newsym sym[50];

int E(int n, newsym *sym);

int T(int n, newsym *sym);

int D(int n, newsym *sym);

int AExpression(int n, newsym *sym);

int Ass(int n, newsym *sym);


void quantity1(int n, newsym *sym);

int quantity2(int n, newsym *sym);

int quantity3(int n, newsym *sym);

int variable2(int n, newsym *sym);

int variable3(int n, newsym *sym);


int compound(int all, newsym *sym);

int call(int all, newsym *sym);


//判断常量说明及定义是否合法

void quantity1(int n, newsym *sym) {

int i, j;

for (i = 0; i<n; i++) {

if (!strcmp(sym[i].restr, "constsym")) {

j = quantity2(i, sym);

if (strcmp(sym[i - 1].restr, "semicolon") && i != 0) {

rg1 = 0;

printf("常量说明/定义前缺少分号\n");

}

else if (j == 1) {

rg1 = 0;

printf("常量说明/定义错误\n");

}

}

}

}


int quantity2(int n, newsym *sym) {

int i = n, k = -1, flag = 0;

while (k != i) {

k = i;

i = quantity3(i + 1, sym);

}

if ((!strcmp(sym[i + 1].restr, "ident") && !strcmp(sym[i + 2].restr, "eql") && !strcmp(sym[i + 3].restr, "number") && !strcmp(sym[i + 4].restr, "semicolon")))

flag = 0;

else

flag = 1;

return flag;

}



int quantity3(int n, newsym *sym) {

if (!strcmp(sym[n].restr, "ident") && !strcmp(sym[n + 1].restr, "eql") && !strcmp(sym[n + 2].restr, "number") && !strcmp(sym[n + 3].restr, "comma"))

return n = n + 3;

else

return n - 1;

}


//判断变量说明及定义是否合法

void variable1(int n, newsym *sym) {

int i, j = 0;

for (i = 0; i<n; i++) {

if (!strcmp(sym[i].restr, "varsym")) {

j = variable2(i, sym);

if (strcmp(sym[i - 1].restr, "semicolon") && i != 0) {

rg1 = 0;

printf("变量说明/定义前缺少分号\n");

}

else if (j == 1) {

rg1 = 0;

printf("变量说明/定义错误\n");

}

}

}

}


int variable2(int n, newsym *sym) {

int i = n, k = -1, flag = 0;

while (k != i) {

k = i;

i = variable3(i + 1, sym);

}

if ((!strcmp(sym[i + 1].restr, "ident") && !strcmp(sym[i + 2].restr, "semicolon")))

flag = 0;

else

flag = 1;

return flag;

}



int variable3(int n, newsym *sym) {

if (!strcmp(sym[n].restr, "ident") && !strcmp(sym[n + 1].restr, "comma"))

return n = n + 1;

else

return n - 1;

}



int E(int n, newsym *sym)//判断表达式

{

int k = 0;

if (!strcmp(sym[n].restr, "plus") || !strcmp(sym[n].restr, "minus"))

{

n++;

if (!strcmp(sym[n - 2].restr, "lparen"))

{

cout << "算数表达式出错" << endl;

rg = 0;

}

if (!strcmp(sym[n].restr, "ident") || !strcmp(sym[n].restr, "number") || !strcmp(sym[n].restr, "lparen"))

{

n = T(n, sym);

}

}

else if (!strcmp(sym[n].restr, "ident") || !strcmp(sym[n].restr, "number") || !strcmp(sym[n].restr, "lparen"))

{

n = T(n, sym);

}

if ((!strcmp(sym[n].restr, "ident") || !strcmp(sym[n].restr, "number")) && (!strcmp(sym[n - 1].restr, "ident") || !strcmp(sym[n - 1].restr, "number")))

{

n++;

cout << "缺运算符" << endl;

rg = 0;

}

if ((!strcmp(sym[n].restr, "ident") || !strcmp(sym[n].restr, "number")) && !strcmp(sym[n - 1].restr, "rparen"))

{

n++;

cout << "缺少运算符" << endl;

rg = 0;

}

while (!strcmp(sym[n].restr, "plus") || !strcmp(sym[n].restr, "minus"))

{

n++;

n = T(n, sym);

}


if (!strcmp(sym[n].restr, "rparen")) {

for (int i = n; i--; i>0)

if (!strcmp(sym[i].restr, "lparen"))

k = 1;

if (k == 0) {

rg = 0;

cout << "缺少左括号" << endl;

}


}


return n;

}


int T(int n, newsym *sym)  //判断项

{

if (!strcmp(sym[n].restr, "ident") || !strcmp(sym[n].restr, "number") || !strcmp(sym[n].restr, "lparen"))

{

n = D(n, sym);

}

else

{

cout << "算数表达式出错" << endl;

rg = 0;

}


while (!strcmp(sym[n].restr, "times") || !strcmp(sym[n].restr, "slash"))

{

n++;

n = D(n, sym);

}

return n;

}


int D(int n, newsym *sym)  //判断因子

{

if (!strcmp(sym[n].restr, "ident") || !strcmp(sym[n].restr, "number"))

{

n++;

}

else if (!strcmp(sym[n].restr, "lparen"))

{

n++;

n = E(n, sym);

if (!strcmp(sym[n].restr, "rparen"))

{

n++;

}

else

{

cout << "算术表达式出错" << endl;

rg = 0;

}

}

else

{

cout << "算数表达式出错" << endl;

rg = 0;

}

return n;

}


int AExpression(int n, newsym *sym) {        //判断是否为算术表达式


n = E(n, sym);

return n;

}


int Ass(int n, newsym *sym) {      //判断赋值语句

int i = 0;

while (i < n) {

if (strcmp(sym[i].restr, "becomes") == 0) {

if (strcmp(sym[i - 1].restr, "ident") == 0) {

if (!strcmp(sym[i + 1].restr, "becomes"))

cout << "赋值符重复" << endl;

else {

i++;

  AExpression(i, sym);

}

}

else {

rg = 0;

cout << "赋值语句错误" << endl;

}

}

i++;

}

return i;

}


int CExpression(int n, newsym *sym) {      //判断条件表达式

int i = 0;

rg = 1;

while (i < n) {

if (strcmp(sym[i].restr, "ifsym") == 0) {

if (strcmp(sym[i+1].restr, "oddsym") == 0)

AExpression(i + 2, sym);

else {

AExpression(i + 1, sym);

if (rg==1) {

if (strcmp(sym[i + 2].restr, "lss") == 0 || strcmp(sym[i + 2].restr, "leq") == 0 || strcmp(sym[i + 2].restr, "gtr") == 0 || strcmp(sym[i + 2].restr, "geq") == 0) {

if (strcmp(sym[i + 3].restr, "lss") == 0 || strcmp(sym[i + 3].restr, "leq") == 0 || strcmp(sym[i + 3].restr, "gtr") == 0 || strcmp(sym[i + 3].restr, "geq") == 0) {

rg2 = 0;

cout << "条件表达式中关系运算符重复" << endl;

}

else if (strcmp(sym[i + 3].restr, "neq") == 0 || strcmp(sym[i + 3].restr, "becomes") == 0 || strcmp(sym[i + 3].restr, "comma") == 0 || strcmp(sym[i + 3].restr, "semicolon") == 0) {

rg2 = 0;

cout << "条件表达式中符号错误" << endl;

}

  else {

  i=AExpression(i + 3, sym);

  if (rg == 0)

  {

  rg2 = 0;

  cout << "条件表达式出错" << endl;

  }

  }

}

else{

rg2 = 0;

cout << "条件表达式缺少关系运算符" << endl;

}

}

}

}

i++;

}

return i;

}


int compound(int all, newsym *sym) {

char queueb[200];

int flag = 0;//记录queueb中的位置

int correct = 1;

int i;

for (i = 0; i <= all; i++) {

if (strcmp(sym[i].restr, "beginsym") == 0 || strcmp(sym[i].restr, "proceduresym") == 0) {

if (strcmp(sym[i].restr, "beginsym") == 0) {

queueb[flag] = 'b';

flag++;

}

else if (strcmp(sym[i].restr, "proceduresym") == 0) {

queueb[flag] = 'p';

flag++;

}

}

//以下是a型和b型的判断

else if (strcmp(sym[i].restr, "endsym") == 0 && i != all) {

//没有begin

if (flag == 0) {

cout << " end前没有begin" << endl;

correct = 0;

}

//以下属于a型:end后应用";"

else if (queueb[flag - 1] == 'b'&&queueb[flag - 2] == 'p') {

if (strcmp(sym[i + 1].restr, "semicolon") != 0) {

cout << queueb[flag - 2] << endl;

cout << queueb[flag - 1] << endl;

cout << " end后面不是分号" << endl;

queueb[flag - 2] = '0';

queueb[flag - 1] = '0';

correct = 0;

}


else {

cout << queueb[flag - 2] << endl;

cout << queueb[flag - 1] << endl;

queueb[flag - 2] = '0';


queueb[flag - 1] = '0';

flag = flag - 2;

}

}

else {

if ((strcmp(sym[i + 1].restr, "semicolon") == 0 && i<all - 1) || (strcmp(sym[i + 1].restr, "period") == 0 && i<all - 1)) {

cout << " end在中间,但后面是分号或者句号" << endl;

queueb[flag - 1] = '0';

correct = 0;

}

else {

queueb[flag - 1] = '0';

flag = flag - 1;

}


}

}

//c型:end后面没有东西

else if (strcmp(sym[i].restr, "endsym") == 0 && i == all) {

queueb[flag - 1] = '0';

correct = 0;

cout << " end后没有标点符号" << endl;

}

//c型:end后面不是"."

else if (strcmp(sym[i].restr, "endsym") == 0 && i == all - 1) {

if (strcmp(sym[i + 1].restr, "period") != 0) {

correct = 0;

queueb[flag - 1] = '0';

cout << " end在末尾,end后面不是句号" << endl;

}


}


}

if (queueb[0] == 'b' || queueb[0] == 'p') {

correct = 0;

cout << " 缺少end" << endl;

}

return correct;

}



int call(int all, newsym *sym) {

int flag = 0;

int correct = 1;

for (int i = 0; i <= all; i++) {

if (strcmp(sym[i].restr, "callsym") == 0) {

if (strcmp(sym[i + 1].restr, "ident") != 0 || strcmp(sym[i + 2].restr, "semicolon") != 0) {

correct = 0;

}

}

}

if (correct == 0)

printf("call语句错误\n");

return correct;

}






int main()

{

ifstream infile("0.txt");

string buffer;

int i = 0, j, n, m, all,k1,k2;

for (n = 0; n <= 49; n++)

{

sym[n].restr[0] = '\0';

}

n = 0;

while (!infile.eof() && infile >> buffer) {

i = j = 0;

if (buffer[0] == '(')

{

while (buffer[i + 1] != ',')

{

i++;

sym[n].restr[j] = buffer[i];

j++;

}

sym[n].restr[j] = '\0';

n++;

}

}

m = n;

all = n - 1;

quantity1(m, sym);

variable1(m, sym);



Ass(m, sym);

CExpression(m, sym);


k1 = compound(all, sym);

k2 = call(all, sym);



if (rg == 1 && rg1 == 1&&rg2 == 1 && k1== 1 && k2 == 1)

cout << "语法正确" << endl;

else {

cout << "--------------" << endl;

cout << "语法错误" << endl;

}

return 0;

}


版权所有:留学生编程辅导网 2020 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。 站长地图

python代写
微信客服:codinghelp