編譯原理上機作業4——LR(0)分析的DFA生成
input檔案
=*i
XSLR
X->S
S->L=R
S->R
L->*R
L->i
R->L
#
code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#define INIT_LIST -1
#define HAVE_LIST 1
using namespace std;
typedef struct grammer
{
char content[24]; // init value: "\0"
int s_pos; // init value: 3
int s_len; // init value: -1
}grammer;
typedef struct item
{
int id;
grammer gram[200]; // init value: see grammer
int next[200]; //init value: all -1
int num;
}item;
/* global variable */
item my_item[200];
item stand;
//queue<item> process;
item process[1000];
char terSymbol[200];
char nterSymbol[200];
char Symbol[400];
int vtnum, vnnum, vnum, id = 0;
int front = 0, rear = 0;
/* functions */
void closure( item & temp );
int is_nterminal( char ch );
int local( char x );
bool do_not_have( int x, item temp );
bool same( item a, item b[] /* b is my_item*/ );
void init( item temp[], int num );
void input();
void add_to_item( int yuan, int sym, item temp );
void add( int i, int j, item temp[], item current );
bool end( item temp );
int local( char x );
int is_nterminal( char ch );
void print_item( );
void next( item & temp );
bool can_closure( item temp );
bool cmp( item a, item b );
int main()
{
freopen( "input.txt", "r", stdin );
init( my_item, 200 );
input();
item ini;
ini.id = 1;
ini.num = 1;
strcpy( ini.gram[0].content, my_item[0].gram[0].content );
ini.gram[0].s_len = strlen( ini.gram[0].content);
ini.gram[0].s_pos = 3;
closure( ini );
next( ini );
id = 1;
my_item[id] = ini;
//add_to_item( my_item[id] );
// process.push( ini );
process[rear++] = ini;
//don't forget :)
my_item[0].id = 1;
// while(!process.empty())
while( front < rear )
{
/* the C++ STL pop() functions doesn't return a value
you need to use front() to r eturn a value
and use pop() to pop the top of the queue
make them happy :) */
// item current = process.front();
// process.pop();
item current = process[front++];
item temp[vnum];
init( temp, vnum );
for( int i = 0; i < vnum; i++ )
{
if( current.next[i] == HAVE_LIST )
{
for( int j = 0; j < current.num; j++ )
add( i, j, temp, current );
closure( temp[i] );
next( temp[i] );
if( same( temp[i], my_item ) )
{
my_item[id].next[i] = id;
}
else
{
add_to_item( current.id, i, temp[i]/*add to my_item[id]*/ );
if( !end( temp[i] ) )
// process.push( temp[i] );
// process[rear++] = temp[i];
process[rear++] = my_item[id-1];
}
}
}
}
print_item();
}
void next( item & temp )
{
for( int i = 0; i < temp.num; i++ )
{
if( temp.gram[i].s_pos < temp.gram[i].s_len )
temp.next[local(temp.gram[i].content[temp.gram[i].s_pos])] = HAVE_LIST;
}
}
void print_item( )
{
for( int i = 0; i < id; i++ )
{
cout << my_item[i].id << endl;
for( int j = 0; j < my_item[i].num; j++ )
{
cout << my_item[i].gram[j].content << " ";
}
cout << endl;
cout << "from:";
for( int t = 0; t < vnum; t++ )
cout << Symbol[t] << " ";
cout << " " << endl;
for( int t = 0; t < vnum; t++ )
cout << my_item[i].next[t] << " ";
cout << endl;
cout << endl;
}
}
bool end( item temp )
{
for( int i = 0; i < temp.num; i++ )
{
if( temp.gram[i].s_pos < temp.gram[i].s_len )
return false;
}
return true;
}
void add_to_item( int yuan, int sym, item temp )
{
/* add temp to my_item set */
int last = id++;
my_item[last] = temp;
my_item[last].id = id;
/* last my_item's point to the new my_item */
my_item[yuan].next[sym] = id;
}
bool cmp( item a, item b )
{
int flag = 0;
for( int i = 0; i < a.num; i++ )
{
flag = 0;
for( int j = 0; j < b.num; j++ )
{
if( !strcmp(a.gram[i].content, b.gram[j].content) )
{
flag = 1;
break;
}
}
if( flag != 1 )
return false;
}
return true;
}
bool same( item a, item b[] /* b is my_item*/ )
{
int flag;
for( int x = 0; x <= id; x++ )
{
if( a.num == b[x].num )
{
if( cmp( a, b[x] ) )
return true;
}
}
return false;
}
void add( int i, int j, item temp[], item current )
{
int s = current.gram[j].s_pos;
int l = current.gram[j].s_len;
if( current.gram[j].content[s] == Symbol[i] )
{
temp[i].gram[temp[i].num] = current.gram[j];
temp[i].gram[temp[i].num].s_pos++;
s = temp[i].gram[temp[i].num].s_pos;
if( s < l )
temp[i].next[local(temp[i].gram[temp[i].num].content[s])] = HAVE_LIST;
temp[i].num++;
}
}
bool can_closure( item temp )
{
for( int i = 0; i < temp.num; i++ )
{
char s = temp.gram[i].content[temp.gram[i].s_pos];
if( is_nterminal(s) )
return true;
}
return false;
}
void closure( item & temp )
{
int f;
// while( can_closure( temp ) )
// {
f++;
for( int i = 0; i < temp.num; i++ ) // closure
{
if(temp.gram[i].s_pos < temp.gram[i].s_len && is_nterminal(temp.gram[i].content[temp.gram[i].s_pos]) != -1 )
{
char x = temp.gram[i].content[temp.gram[i].s_pos];
if( is_nterminal(x) )
{
for( int h = 0; h < my_item[0].num; h++ )
{
if( my_item[0].gram[h].content[0] == x && do_not_have( h, temp ) )
{
strcpy( temp.gram[temp.num].content, my_item[0].gram[h].content );
temp.gram[temp.num].s_pos = 3;
temp.gram[temp.num].s_len = strlen( temp.gram[temp.num].content);
temp.num++;
temp.next[local(x)] = HAVE_LIST;
}
}
}
}
}
// }
}
bool do_not_have( int x, item temp )
{
for( int i = 0; i < temp.num; i++ )
{
if( !strcmp( my_item[0].gram[x].content, temp.gram[i].content)
&& my_item[0].gram[x].s_pos == temp.gram[i].s_pos )
return false;
}
return true;
}
void init( item temp[], int num )
{
for( int i = 0; i < num; i++ )
{
temp[i].id = -1;
temp[i].num = 0;
for( int j = 0; j < 200; j ++ )
{
temp[i].next[j] = -1;
strcpy( temp[i].gram[j].content, "\0" );
temp[i].gram[j].s_pos = 3;
temp[i].gram[j].s_len = -1;
}
}
}
void input()
{
char temp[30], i = 0;
printf( "please input terminal-Symbol\n" );
scanf( "%s", terSymbol );
printf( "plaese input no-terminal-Symbol\n" );
scanf( "%s", nterSymbol );
vtnum = strlen( terSymbol );
vnnum = strlen( nterSymbol );
strcpy( Symbol, nterSymbol );
strcat( Symbol, terSymbol );
vnum = vtnum + vnnum;
printf( "please input the grammer(end with #):\n" );
i = 0;
while( scanf( "%s", temp ) && temp[0] != '#' )
{
strcpy( my_item[id].gram[i].content, temp );
my_item[id].gram[i].s_len = strlen(temp);
my_item[id].gram[i].s_pos = 3;
i++;
}
my_item[id].num = i;
}
int local( char x )
{
for( int i = 0; i < vnum; i++ )
if( Symbol[i] == x )
return i;
return -1;
}
int is_nterminal( char ch )
{
for( int i = 0; i < vnnum; i++ )
if( ch == nterSymbol[i] )
return i;
return -1;
}
相關文章
- 編譯原理上機作業1——詞法分析器編譯原理詞法分析
- 編譯原理上機作業2——LL(1)語法分析編譯原理語法分析
- 編譯原理上機作業3——算符優先演算法編譯原理演算法
- 《編譯原理》LR 分析法與構造 LR(1) 分析表的步驟 - 例題解析編譯原理
- 編譯器前端之如何實現基於DFA的詞法分析器編譯前端詞法分析
- 編譯原理作業小結編譯原理
- Hollis原創|深入分析Java的編譯原理Java編譯原理
- 管理上的操作原則
- Go編譯原理系列4(語法分析)Go編譯原理語法分析
- 編譯器如何生成彙編編譯
- 編譯原理第一章作業編譯原理
- Needle:基於 DFA 的正規表示式庫,可編譯為 JVM 位元組碼編譯JVM
- MongoDB(0)- 原始碼編譯MongoDB原始碼編譯
- 《作業系統真象還原》——0.18編譯型程式與解釋型程式的區別作業系統編譯
- 原創 【CentOS Linux 7】實驗4【gcc編譯器】CentOSLinuxGC編譯
- 大學計算機必修課新講--編譯原理+作業系統+圖形學計算機編譯原理作業系統
- android 刷機ROM結構與編譯製作。Android編譯
- WebAssembly 系列(三)編譯器如何生成彙編Web編譯
- 0916編譯原理第二次作業編譯原理
- Linux作業系統核心編譯詳解(2)(轉)Linux作業系統編譯
- 機器學習作業4機器學習
- keil編譯不能生成“.HEX”的解決方法編譯
- gulp4增量編譯編譯
- 核心編譯part4編譯
- oracle11g編譯生成bbedOracle編譯
- Linux作業系統上編譯程式的方法詳細介紹Linux作業系統編譯
- JavaScript的預編譯過程分析JavaScript編譯
- 從原理上搞定編碼-- Base64編碼
- .NET 中的動態編譯(生成exe檔案)編譯
- PPO演算法動作機率出現[0,0,0,0,0,1]的問題演算法
- 翻譯的未來:翻譯機器和譯後編譯編譯
- 團隊作業4
- 製作交叉編譯工具鏈概述編譯
- Vue3原始碼分析——編譯模組和編譯器Vue原始碼編譯
- icu4c-icu4c-68.1編譯編譯
- 程式的編譯和連結原理分析編譯
- 編譯程式(compiler)的簡單分析編譯Compile
- mingw 編譯生成的dll 如何在vs中使用編譯