資源簡介
第三次上機作業(yè)
1. 編寫First和Follow函數(shù),實現(xiàn)其求解過程。
(1)FIRST集合計算方法:
① 若X?a.., 則將終結(jié)符a加入FIRST(X)中;
② 若X??,則將?加入FIRST(X)中;
③ 若X?Y…,且Y屬于非終結(jié)符,則將FIRST(Y)\{?}加入到FIRST(X)中;(注:“\”表示除去?元素,即FIRST(Y)中的非?元素加入到FIRST(X)中。以下同理。)
④ 若X?Y1Y2..YK,且Y1,Y2,..Yi-1都是非終結(jié)符,且Y1,Y2,..Yi-1的FIRST集合中均包含?,則將FIRST(Yj)的所有非?元素加入到FIRST(X)中,(j=1,2,..i).特別地,若Y1~YK均有?產(chǎn)生式,則將?加到FIRST(X)中。
(2)FOLLOW集合計算方法:
① 對文法開始符號S,置$于FOLLOW(S)中。
② 若有A??B?,則將FIRST(?)\{?} 加入FOLLOW(B)中。 (此處? 可以為空)
③ 若A?? B 或A?? B ?,且 ? ?* ?(即? 屬于FIRST(?)),則將 FOLLOW(A)加入FOLLOW(B)中(此處? 可以為空)。
2. 測試文法:
A->BCDE
B->aBA|ε
C->F|ε
D->b|c|ε
E->e|ε
F->d|ε
代碼片段和文件信息
#include
#include
#include
#include
using?namespace?std;
#define?MAX?50
int?NONE[MAX]?=?{?0?};
string?strings;???????//產(chǎn)生式
string?Vn;???????????//非終結(jié)符
string?Vt;???????????//終結(jié)符
string?first[MAX];??//存放每個終結(jié)符的first集
string?First[MAX];??//存放每個非終結(jié)符的first集
string?Follow[MAX];?//存放每個非終結(jié)符的follow集
int?N;???????????????//產(chǎn)生式個數(shù)
struct?STR
{
string?left;
string?right;
};
void?rec(STR?*p)?????????????????//識別Vn和Vt
{
int?i?j;
for?(i?=?0;i? {
for?(j?=?0;j?(int)p[i].left.length();j++)//左側(cè)
{
if?((p[i].left[j]?>=?‘A‘&&p[i].left[j]?<=?‘Z‘))????????????????//左側(cè)第j個字母是大寫
{
if?(Vn.find(p[i].left[j])>100)?????????????????????????????//Vn里沒找到返回很大的值
Vn?+=?p[i].left[j];
}
else
{
if?(Vt.find(p[i].left[j])>100)???????????????????????????//小寫字母放Vt
Vt?+=?p[i].left[j];
}
}
for?(j?=?0;j?(int)p[i].right.length();j++)//右側(cè)
{
if?(!(p[i].right[j]?>=?‘A‘&&p[i].right[j]?<=?‘Z‘))
{
if?(Vt.find(p[i].right[j])>100)
Vt?+=?p[i].right[j];
}
else
{
if?(Vn.find(p[i].right[j])?>?100)
Vn?+=?p[i].right[j];
}
}
}
}
void?getlr(STR?*p?int?i)?????????????????????????????????????????????//將產(chǎn)生式的左右部分別放入left,right
{
int?j;
for?(j?=?0;j {?if?(strings[j]?==?‘-‘&&strings[j?+?1]?==?‘>‘)
{?p[i].left?=?strings.substr(0?j);
??p[i].right?=?strings.substr(j?+?2?strings.length()?-?j);
}
}
}
string?Letter_First(STR?*p?char?ch)
{
int?t;
if?(!(Vt.find(ch)>100))????????????????????????//在Vt里,first就是自身
{
first[Vt.find(ch)]?=?ch;
return?first[Vt.find(ch)?-?1];
}
if?(!(Vn.find(ch)?>?100))??????????????????????//在Vn中的第i個
{
for?(int?i?=?0;i? {
if?(p[i].left[0]?==?ch)?????????????//左側(cè)字符是ch
{
if?(!(Vt.find(p[i].right[0])>100))
{
if?(First[Vn.find(ch)].find(p[i].right[0])?>?100)?????//右側(cè)第一個字符是Vt,加入Vni的first集合中
{
First[Vn.find(ch)]?+=?p[i].right[0];
}
}
if?(p[i].right[0]?==?‘#‘)
{
if?(First[Vn.find(ch)].find(‘#‘)?>?100)???????????//右側(cè)第一個字符是空,加入Vni的first集合中
{
First[Vn.find(ch)]?+=?‘#‘;
}
}
if?(!(Vn.find(p[i].right[0])?>?100))????????????????//右側(cè)第一個字母是Vn
{
if?(p[i].right.length()?==?1)??????????????????????//只有一個字母
{
string?ff;
ff?=?Letter_First(p?p[i].right[0]);????????????????????????//把右側(cè)字母的first集合加入到左側(cè)字母中
for?(int?k?=?0;k? {
if?(First[Vn.find(ch)].find(ff[k])>100)
{
First[Vn.find(ch)]?+=?ff[k];
}
}
}
else???????????????????????????????????????????????//多個字母都是Vn
{
for?(int?j?=?0;j? {
string?TT;
TT?=?Letter_First(p?p[i].right[j]);
if?(!(TT.find(‘#‘)>100)?&&?(j?+?1)?
- 上一篇:姿態(tài)解算c代碼
- 下一篇:C++中文分詞系統(tǒng)代碼
評論
共有 條評論