狠狠干影院/欧美午夜电影在线观看/高黄文/国产精品一区二区在线观看完整版

編譯原理實驗報告

| 瀏覽次數:

  編譯原理實驗報告

 Compilers Principles Experiment Report

 所在學院:

 所在班級:

 學生姓名:

 學

 號:

  指導教師:

 教

 務

 處

 2015 年 12 月

 詞法分析程序

  一、實驗目的:

 設計、編制和調試一個具體的詞法分析程序,加深對詞法分析的理解。

 二、實驗要求:

 1、通過對 PL/0 詞法分析程序(GETSYS)的分析,編制一個具有以下功能的詞法分析程序:

 a.輸入為字符串(或待進行詞法分析的源程序),輸出為單詞串,即由(單詞,類別)所組成的二元組序列;

 b.有一定的錯誤檢查能力,例如能發現 2a這類

  不能作為單詞的字符串。

 三、實驗代 碼

 #define ID 12//標識符

 #define INT 13//常數

 #define JF 14//界符

 #define YSF 15//運算符

 #define N 30//字符讀取的最大長度

 char TOKEN[N];

 FILE *write;

 //查詢一個字符串,看其是否與指定的字符相匹配,如果匹配返回 1 個非零的值,如果不匹配,則返回一個 0 值*/

 int looksame(char *a)

 {

  int i;

  char*key[22] = { "begin","end","if","then","else","for","do","while","and","or","not","BEGIN","END","IF","THEN","ELSE","FOR","DO","WHILE","AND","OR","NOT" };

  for (i = 0;i < 22;i++)

  {

 if (strcmp(key[i], a) == 0)//該字符串是否與關鍵字相匹配

  return (i % 11 + 1);

  }

  return 0;

 }

  //把 a輸入到指定文件中,然后從該文件中讀出字符串,放到一個數組中輸出

 void out(int a, char *b)

 {

  FILE *write;

  write = fopen("E:\\b.txt", "a+");

  if (write == NULL)

  {

 printf("文件打開失敗");

 exit(0);

  }

  fprintf(write, "%d\t", a);

  fwrite(b, strlen(b), 1, write);

  fprintf(write, "\n");

  fclose(write);

  printf("%d %20s\t\t", a, b);

 }

 int error()

 {

  printf("書寫格式錯誤,未被識別\n");

  return 0;

 }

 void function(FILE *fp)

 {

  char ch = " ";

  int i, c;

  while (ch != EOF)

  {

 ch = fgetc(fp);//從文件中讀取字符

 while (ch == " " || ch == "\t" || ch == "\n") {

  ch = fgetc(fp);

 }

 if (isalpha(ch)) //isalpha()判斷是否為英文字母,是則返回非

 零值,否則返回零

 {

  TOKEN[0] = ch;

  ch = fgetc(fp);

  i = 1;

  while (isalnum(ch))

  //isalnum()判斷字符是否為英文字

 母或數字,如果是則返回非零值,如果不是則返回零//

  {

 TOKEN[i] = ch;

 i++;

 ch = fgetc(fp);

  }

  TOKEN[i] = "\0";

  fseek(fp, -1, 1);

  //用于二進制方式打開的文件,移動文件讀寫指針位置

  c = looksame(TOKEN);

  if (c == 0)

  {

 out(ID, TOKEN);printf("標識符\n");

  }

  else

  {

 out(c, TOKEN);printf("關鍵字\n");

  }

 }

 else if (isdigit(ch))

  //isdigit()判斷是否為0-9 的數字

 {

  TOKEN[0] = ch;

  ch = fgetc(fp);

  i = 1;

  while (isdigit(ch))

  {

 TOKEN[i] = ch;

 i++;

 ch = fgetc(fp);

  }

  TOKEN[i] = "\0";

  fseek(fp, -1, 1);

  out(INT, TOKEN);

  printf("常數\n");

 }

 else

 {

  switch (ch)

  {

  case"+":out(YSF, "+");printf("運算符\n");

 break;

  case"-":out(YSF, "-");printf("運算符\n");

 break;

  case";":out(JF, ";");printf("界符\n");

 break;

  case",":out(JF, ",");printf("界符\n");

 break;

  case"|":out(YSF, "|");printf("運算符\n");

 break;

  case"{":out(JF, "{");printf("界符\n");

 break;

  case"(":out(JF, "(");printf("界符\n");

 break;

  case"!":out(JF, "!");printf("界符\n");

 break;

  case"^":out(JF, "^");printf("界符\n");

 break;

  case")":out(JF, ")");printf("界符\n");

 break;

  case"}":out(JF, "}");printf("界符\n");

 break;

  case"<":ch = fgetc(fp);

 if (ch == "=")

 {

  out(YSF, "<=");

  printf("運算符\n");

 }

  else if (ch == ">")

 {

  out(YSF, "<>");

  printf("運算符\n");

 }

 else

 {

  fseek(fp, -1, 1);

  out(YSF, "<");

  printf("運算符\n");

 }

 break;

  case"=":out(YSF, "=");printf("運算符\n");

 break;

  case">":ch = fgetc(fp);

 if (ch == "=")

 {

  out(YSF, ">=");

  printf("運算符\n");

 }

 else

 {

  fseek(fp, -1, 1);

  out(YSF, ">");

  printf("運算符\n");

 }

 break;

  case":":ch = fgetc(fp);

 if (ch == "=")

 {

  out(YSF, ":=");

  printf("運算符\n");

 }

 else

 {

  fseek(fp, -1, 1);

  out(JF, ":");

  printf("界符\n");

 }

 break;

  case"/":ch = fgetc(fp);

 if (ch == "*")

 {

  out(JF, "/*");

  printf("界符\n");

  while (1)//注釋的內容在詞法分析中不顯示

 while (ch != "/")

  ch = fgetc(fp);

  fseek(fp, -2, 1);

  ch = fgetc(fp);

  if (ch == "*")

  {

 fseek(fp, 1, 1);

 break;

  }

  else

  {

 fseek(fp, 2, 1);

 ch = fgetc(fp);

  }

  fseek(fp, -2, 1);

 }

 else

 {

  fseek(fp, -1, 1);

  out(JF, "/");

  printf("界符\n");

 }

 break;

  case"*":ch = fgetc(fp);

 if (ch == "/")

 {

  out(JF, "*/");

  printf("界符\n");

 }

 else

 {

  fseek(fp, -1, 1);

  out(YSF, "*");

  printf("運算符\n");

 }

 break;

  case EOF:break;

  default:error();

 break;

 }

  }

 }

 }

 int main()

 {

  FILE *read;

  read = fopen("E:\\a.txt", "r");

  write = fopen("E:\\b.txt", "a+");

  if (read == NULL)

  {

 printf("FILE OPEN FAIL!");

 exit(0);

  }

  printf("===========================================================\n");

  printf("====================詞法分析程序===========================\n");

  printf("===========該分析程序的文件存放在E:\\a.txt 目錄下==========\n");

  printf("===========該程序的分析結果存放在E:\\b.txt 目錄下===========\n");

  printf("===============================

 =============================\n");

  function(read);

  fclose(read);

  system("pause");

  return 0;

 }

 四、實驗截圖

  a.txt

 b.txt

 基于 LL(1)方法的語法分析程序

 一、 實驗目的

 設計、編制和調試一個典型的語法分析方法,進一步掌握常用的語法分析方法。

 二、實驗要求

 1、根據 LL(1)分析法編寫一個語法分析程序,可根據自己實際情況,選擇以下一項作為分析算法的輸入:

  a.直接輸入根據已知文法構造的分析表 M;

  b.輸入文法的 FIRST(α)和 FOLLOW(U)集合,由

 程序自動生成文法的分析表 M;

  c.輸入已知文法,由程序自動構造文法的分析表M。

 2、程序具有通用性

 所開發的程序可適用于不同的文法和任意輸入串,且能判斷該文法是否為 LL(1)文法。

 3、有運行實例

 對于輸入的文法和符號串,所編制的語法分析程序應能正確判斷此串是否為文法的句子,并要求輸出分析過程。

 三、實驗代碼

 #include "stdafx.h"

 #include<stdio.h>

 #include<stdlib.h>

 #include<string.h>

 #include<dos.h>

 char A[20];/*分析棧*/

 char B[20];/*剩余串*/

 char v1[20] = { "i","+","*","(",")","#" };/*終結符

 */

 char v2[20] = { "E","G","T","S","F" };/*非終結符

  */

  int j = 0, b = 0, top = 0, l;/*L 為輸入串長度 */

  typedef struct type

  /*產生式類型定義

 */

 {

  char origin; /*大寫字符

 */

  char array[5]; /*產生式右邊字符 */

  int length; /*字符個數

 */

 }type;

  type e, t, g, g1, s, s1, f, f1;/*結構體變量

 */

 type C[10][10];/*預測分析表

 */

  void print()/*輸出分析棧

 */

 {

  int a;/*指針*/

  for (a = 0;a <= top + 1;a++)

 printf("%c", A[a]);

  printf("\t\t");

 }/*print*/

  void print1()/*輸出剩余串*/

 {

  int j;

  for (j = 0;j<b;j++)/*輸出對齊符*/

 printf(" ");

  for (j = b;j <= l;j++)

 printf("%c", B[j]);

  printf("\t\t\t");

 }

 int _tmain(int argc, _TCHAR* argv[])

 {

  int m, n, k = 0, flag = 0, finish = 0;

  char ch, x;

  type cha;/*用來接受 C[m][n]*/

 /*把文法產生式賦值結構體*/

  e.origin = "E";

  strcpy(e.array, "TG");

  e.length = 2;

  t.origin = "T";

  strcpy(t.array, "FS");

  t.length = 2;

  g.origin = "G";

  strcpy(g.array, "+TG");

  g.length = 3;

  g1.origin = "G";

  g1.array[0] = "^";

  g1.length = 1;

  s.origin = "S";

  strcpy(s.array, "*FS");

  s.length = 3;

  s1.origin = "S";

  s1.array[0] = "^";

  s1.length = 1;

  f.origin = "F";

  strcpy(f.array, "(E)");

  f.length = 3;

  f1.origin = "F";

  f1.array[0] = "i";

  f1.length = 1;

 for (m = 0;m <= 4;m++)/*初始化分析表*/

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

  C[m][n].origin = "N";/*全部賦為空*/

  /*填充分析表*/

  C[0][0] = e;C[0][3] = e;

  C[1][1] = g;C[1][4] = g1;C[1][5] = g1;

  C[2][0] = t;C[2][3] = t;

  C[3][1] = s1;C[3][2] = s;C[3][4] = C[3][5] = s1;

  C[4][0] = f1;C[4][3] = f;

  printf("提示:本程序只能對由"i","+","*","(",")"構成的

 以"#"結束的字符串進行分析,\n");

  printf("請輸入要分析的字符串:");

  do/*讀入分析串*/

  {

 scanf("%c", &ch);

 if ((ch != "i") && (ch != "+") && (ch != "*") && (ch != "(") && (ch != ")") && (ch != "#"))

 {

  printf("輸入串中有非法字符\n");

  exit(1);

 }

 B[j] = ch;

 j++;

  } while (ch != "#");

  l = j;/*分析串長度*/

  ch = B[0];/*當前分析字符*/

  A[top] = "#"; A[++top] = "E";/*"#","E"進棧*/

  printf("步驟\t\t 分析棧 \t\t 剩余字符 \t\t 所用產生式 \n");

  do

  {

 x = A[top--];/*x 為當前棧頂字符*/

 printf("%d", k++);

 printf("\t\t");

 for (j = 0;j <= 5;j++)/*判斷是否為終結符*/

  if (x == v1[j])

  {

 flag = 1;

 break;

  }

 if (flag == 1)/*如果是終結符*/

 {

  if (x == "#")

  {

 finish = 1;/*結束標記*/

 printf("acc!\n");/*接受 */

 getchar();

 getchar();

 exit(1);

  }/*if*/

  if (x == ch)

  {

 print();

 print1();

 printf("%c匹配\n", ch);

 ch = B[++b];/*下一個輸入字符*/

 flag = 0;/*恢復標記*/

  }/*if*/

  else/*出錯處理*/

  {

 print();

 print1();

 printf("%c出錯\n", ch);/*輸出出錯終結符*/

 exit(1);

  }/*else*/

 }/*if*/

 else/*非終結符處理*/

 {

  for (j = 0;j <= 4;j++)

 if (x == v2[j])

 {

  m = j;/*行號*/

  break;

 }

  for (j = 0;j <= 5;j++)

 if (ch == v1[j])

 {

  n = j;/*列號*/

  break;

 }

  cha = C[m][n];

  if (cha.origin != "N")/*判斷是否為空*/

  {

 print();

 print1();

 printf("%c->", cha.origin);/*輸出產生式*/

 for (j = 0;j<cha.length;j++)

  printf("%c", cha.array[j]);

 printf("\n");

 for (j = (cha.length - 1);j >= 0;j--)/*產生式逆序入棧*/

  A[++top] = cha.array[j];

 if (A[top] == "^")/*為空則不進棧*/

  top--;

  }/*if*/

  else/*出錯處理*/

  {

 print();

 print1();

 printf("%c出錯\n", x);/*輸出出錯非終結符*/

 exit(1);

  }/*else*/

 }/*else*/

  } while (finish == 0);

  return 0;

 }

 四、 實驗截圖

  于 基于 LR(0) 方法的語法分析程序

 一、實驗目的

 設計、編制和調試一個典型的語法分析方法,進一步掌握常用的語法分析方法。

 二、實驗要求

 可根據自己實際情況,選擇以下一項作為分析算法的輸入:

 (1)直接輸入根據己知文法構造的 LR(0)分析表。

 (2)輸入已知文法的項目集規范族和轉換函數,由程序自動生成 LR(0)分析表; (3)輸入已知文法,由程序自動生成 LR(0)分析表。

 三、程序代碼

 #include "stdafx.h"

 #include<iostream>

 #include<string.h>

 #include<iomanip>

 #include<stdlib.h>

 using namespace std;

 struct stack {

  int

 top;

  int

 st[15];

  //狀態棧

  char sn[15];

  //符號棧

 }*sign;

 struct analysis {

  //動作表結構

  char act;

  int

 status;

 }action[][6] = {

  {

 "s",5,"$",0,"$",0, "s",4,"$",0, "$",0

  },

  {

 "$",0,"s",6,"$",0, "$",0,"$",0, "A",0

  },

  {

 "$",0,"r",2,"s",7, "$",0,"r",2, "r",2

  },

  {

 "$",0,"r",4,"r",4, "$",0,"r",4, "r",4

  },

  {

 "s",5,"$",0,"$",0, "s",4,"$",0, "$",0

  },

  {

 "$",0,"r",6,"r",6, "$",0,"r",6, "r",6

  },

  {

 "s",5,"$",0,"$",0, "s",4,"$",0, "$",0

  },

  {

 "s",5,"$",0,"$",0, "s",4,"$",0, "$",0

  },

  {

 "$",0,"s",6,"$",0, "$",0,"s",11,"$",0

  },

  {

 "$",0,"r",1,"s",7, "$",0,"r",1, "r",1

  },

  {

 "$",0,"r",3,"r",3, "$",0,"r",3, "r",3

  },

  {

 "$",0,"r",5,"r",5, "$",0,"r",5, "r",5

  }

 };

 analysis G[] = {

  {

 "E",3

  },{

 "E",1

  },{

 "T",3

  },{

 "T",1

  },{

 "F",3

  },{

 "F",1

  }

 };

  //此文法信息

 int go[][3] = {

  1,2,3,99,99,99,99,99,99,99,99,99,8,2,3,99,99,99,99,9,3,99,99,10,99,99,99,99,99,99,99,99,99,99,99,99

 };

 int index(char m) {

  int id;

  if ((m == "i") || (m == "E"))

  id = 0;

  else if ((m == "+") || (m == "T"))

 id = 1;

  else if ((m == "*") || (m == "F"))

 id = 2;

  else if (m == "(")

 id = 3;

  else if (m == ")")

 id = 4;

  else if (m == "#")

 id = 5;

  else

  id = 99;

  return id;

 }

 void main() {

  cout << "參照文法為:\n" << "(1)E→E+T\n" << "(2)E→T\n" << "(3)T→T*F"\n"\

 << "(4)T→F\n" << "(5)F→(E)\n" << "(6)F→i\n";

  char instr[20], *current, a;

  int i = 0, step = 0, ix1, ia, ix2, ig, iG, back;

  bool flag = true;

  sign = new stack;

  cout << "請輸入待分析的字符串(以#結束):\n";

  do {

 cin >> instr[i++];

  } while (instr[i - 1] != "#");

  instr[i] = "\0";

  current = instr;

  sign->st[0] = 0;sign->sn[0] = "#";sign->sn[1] = "\0";sign->top = 0;

  cout << "步驟" << setw(20) << "狀

 態" << setw(20) << "符

 號" << setw(20) << "輸 入 串\n";

  cout << "====" << setw(20) << "======" << setw(20) << "======" << setw(20) << "========\n";

  cout << step++ << setw(20) << sign->st[0] << setw(21) << sign->sn << setw(21) << instr << endl;

  while (flag) {

 cout << step++ << setw(20);

 a = *current;ia = index(a);

 ix1 = sign->st[sign->top]; //cout<<a<<" "<<ia<<" "<<ix1<<" "<<action[ix1][ia].act;

 //hhjhj

 if (ia == 99) {

  cout << "此文法無法識別該輸入串!";

  break;

 }

 if (action[ix1][ia].act == "s") {

  sign->top += 1;

  sign->sn[sign->top] = a;

  sign->sn[(sign->top) + 1] = "\0";

  sign->st[sign->top] = action[ix1][ia].status;

  current++;

 }

 else if (action[ix1][ia].act == "r") {

  iG = action[ix1][ia].status - 1;

 //零下表開始

  back = G[iG].status;

  sign->top -= back;

  ix2 = sign->st[sign->top];

  ig = index(G[iG].act);

  if (go[ix2][ig] != 99)

 sign->top += 1;

 sign->st[sign->top] = go[ix2][ig];

 sign->sn[sign->top] = G[iG].act;

 sign->sn[(sign->top) + 1] = "\0";

  }

  else {

 cout << "此文法無法識別該輸入串!";

 break;

  }

 }

 else if (action[ix1][ia].act == "$") {

 cout << "此文法無法識別該輸入串!";

  break;

 }

 else if (action[ix1][ia].act == "A") {

 flag = false;

 }

 for (i = 0;i <= sign->top;i++)

  cout << sign->st[i] << " ";

 cout << setw(20 - (sign->top)) << sign->sn << setw(20 - strlen(sign->sn)) << current << endl;

 if (flag == false)

  cout << "文法分析成功!" << endl;

  }

 }

 四、實驗截圖

  中間代碼生成程序(逆波蘭表示)

 一、實驗目的

  加深對語義翻譯的理解

 二、實驗要求

 (1)編制一個中間代碼生成程序,能將算術表達式等翻譯成逆波蘭形式; (2)程序具有通用性,即能接受各種不同的算術表達式等語法成分。

 (3)有運行實例.對于語法正確的算術表達式,能生成逆波蘭表示,并輸出結果;對不正確的表達式,能檢測出錯誤。

 (4)

 提交實習報告,報告內容應包括:

 目的、要求,算法描述,程序代碼,運行截圖 三、程序代碼

 #include "stdafx.h"

 #include <iostream>

 #include <string>

 using namespace std;

 class Transform

 {

 private:

 char s_stack[20];//棧

  string s_result;//轉換之后的字符串,也就是后綴表達式

  int top;//棧頂

 public:

  Transform()

  {

 top=0;

 s_stack[0]="#";

 s_result="";

  }

  void pop()

  {

 top--;

  }

  void push(char b)

  {

 top++;

 s_stack[top]=b;

  }

  string TF(string a)

  {

 bool q=0;

 for (int i=0;i<a.length();i++)

 {

  switch (a[i])

  {

  case "+":

 case "-":

 q=1;

 if (s_stack[top]!="*"&&s_stack[top]!="/"&&s_stack[top]!="@"&&s_stack[top]!="+"&&s_stack[top]!="-")

 {

  push(a[i]);

 }

 else

 {

  while(s_stack[top]=="*"||s_stack[top]=="/"||s_stack[top]=="@"||s_stack[top]=="+"||s_stack[top]=="-")

  {

 s_result+=s_stack[top];

 pop();

  }

  push(a[i]);

 }

 break;

  case "*":

  case "/":

 q=1;

 if (s_stack[top]!="@"&&s_stack[top]!="*"&&s_stack[top]!="/")

 {

  push(a[i]);

 }

 else

 {

  while(s_stack[top]=="@"||s_stack[top]=="*"||s_stack[top]=="/")

  {

 s_result+=s_stack[top];

  pop();

  }

  push(a[i]);

 }

 break;

 case ":=":

 q=1;

 if (s_stack[top]!="*"&&s_stack[top]!="/"&&s_stack[top]!="@"&&s_stack[top]!="+"&&s_stack[top]!="-")

 {

  push(a[i]);

 }

 else

 {

  while(s_stack[top]=="*"||s_stack[top]=="/"||s_stack[top]=="@"||s_stack[top]=="+"||s_stack[top]=="-")

  {

 s_result+=s_stack[top];

 pop();

  }

 push(a[i]);

 }

 break;

  case "@"://負號

 q=1;

 if (s_stack[top]!="@")

 {

  push(a[i]);

 }

 else

 {

  while(s_stack[top]=="@")

  {

 s_result+=s_stack[top];

 pop();

  }

 push(a[i]);

 }

 break;

  case "(":

 q=1;

 push(a[i]);

 break;

  case ")":

 q=1;

 while(s_stack[top]!="(")

 {

  s_result+=s_stack[top];

  pop();

 }

 pop();//遇到第一個匹配的(

 while(s_stack[top]!="(")//可能有第二、三、四、、、、個(,

  如果有,遇到會停

 {

  if(s_stack[top]=="#")break;

  s_result+=s_stack[top];

  pop();

 }

 break;

  }

  if (q==0)

  {

 s_result+=a[i];

  }

  else

  {

 q=0;

  }

 }

 while(s_stack[top]!="#")//把棧中的字符都出棧

 {

  s_result+=s_stack[top];

 pop();

 }

 s_result+=s_stack[top];//末尾加上#

 return s_result;

  }

  };

 void main()

 {

  cout<<"請輸入表達式(取反用@表示,以#結束)";

  string s_in;

  string s_out;

  cin>>s_in;

  Transform T;

  s_out=T.TF(s_in);

  cout<<"逆波蘭表達式為:"<<s_out<<endl;

  system("pause");

 }

 四、實驗截圖

 封面設計:

 賈麗

 地 址:中國河北省秦皇島市河北大街 438 號

 郵 編:066004

 電 話:0335-8057068

 傳 真:0335-8057068

 網 址:http://jwc.ysu.edu.cn

推薦訪問: 編譯 原理 實驗

【編譯原理實驗報告】相關推薦

工作總結最新推薦

NEW