?? parse.cpp
字號:
match(Lex::TOKEN);
index=symtype();
nlist(index,0,0);
break;
case Lex::LEFT:
case Lex::RIGHT:
case Lex::NONASSOC:
++curPrec; // current precedence.
match(lookahead);
index=symtype();
nlist(index,lookahead,curPrec);
break;
case Lex::TYPE:
match(Lex::TYPE);
index=symtype();
nlist2(index);
break;
case Lex::START:
match(Lex::START);
if(Lex::ID == lookahead)
{
index=isinVns(lex.strval);
if(index == -1)
{ // 如果開始符號沒有事先定義.
S=insert_Vns(lex.strval,-1);
//nontUnion.push_back(-1);
}
else
{
S=index;
}
match(Lex::ID);
}
else
{//error
err_msg<<"\"%start\"后缺少標識符.";
fatal();
}
//defines();
break;
case Lex::UNION:
eat_up_union();
Continue=True;
match(Lex::UNION);
break;
default:
Continue=False;
break;
}//switch(lookahead)
}// while(Continue)
}
//symtype: /* empty */
// | '<' eat_up_symtype '>'
// ;
sint32
Parse::symtype()
{ // 返回值為 -1 表明不存在 <xxx>定義.
if('<'==lookahead)
{// 將 "<xx>" 中的全部內容讀入stype中.
string sval;
sint32 index;
register c=lex.pf.get();
sval.clear();
while('>'!=c && Lex::ENDOFFILE!=c)
{
sval+=c;
c=lex.pf.get();
}
if(Lex::ENDOFFILE==c)
{
err_msg<<"非正常的文件結束.";
fatal();
}
// if( !sval.empty() )
// 不管 “<xx>”中是否有內容均將其插入sUnion中。
// 因此注釋 if 判斷語句。
{
vector<string>::const_iterator iter =
std::find(sUnion.begin(),sUnion.end(),sval);
if( iter==sUnion.end() )
{
sUnion.push_back(sval);
index=sUnion.size()-1;
}
else
index=iter - sUnion.begin();
}
//else
//{
// index = -1;
//}
match('<');
return index;
}// if
else
return -1;
}
//nlist : factor
// | factor nlist
// | factor ',' nlist
// ;
//factor: ID
// | ID NUM /* there has a error for TYPE */
// | ASC
// | ASC NUM
// ;
Void
Parse::nlist(const sint32 stype , sint32 cur_assoc ,sint32 cur_prec)
{ // assoc=0 表示未指定結合率.prec=0 表示未指定優先級.
register sint32 index;
while(Lex::ID == lookahead || Lex::ASC == lookahead)
{
index=isinVts(lex.strval);
if(-1 == index)
{
index = insert_Vts(lex.strval,cur_assoc,cur_prec,
stype,lex.numval);
//tPrec.push_back(cur_prec);
//tAssoc.push_back(cur_assoc);
//tNumVal.push_back(-1); // -1 表示未指定值.
//tUnion.push_back(stype);
}
else
{ // 符號重定義.
tPrec[index]=cur_prec;
tAssoc[index]=cur_assoc;
//tNumVal[index]= -1;
tUnion[index]=stype;
}
match(lookahead);
if(Lex::NUM == lookahead)
{
tNumVal[index]=lex.numval;
match(Lex::NUM);
}
if(',' == lookahead)
match(',');
}// while()
}
//nlist2 : factor2
// | factor2 nlist2
// | factor2 ',' nlist2
// ;
//factor2: ID
// | ASC
// ;
Void
Parse::nlist2(const sint32 stype)
{// 在%type定義中,如果出現終結符則僅給其 union值域賦值,否則作為非終結符處理.
register sint32 index;
if( -1 == stype )
{
err_msg<<"關鍵字 '%type' 后必須包含 '<xxx>' 說明.";
showErr();
}
while( Lex::ID == lookahead || Lex::ASC==lookahead )
{
if ( Lex::ASC==lookahead )
{
if( (index=isinVts(lex.strval)) == -1)
insert_Vts(lex.strval,0,0,stype,lex.numval);
else
tUnion[index] = stype;
}
else
{
if((index=isinVts(lex.strval)) != -1)
{ // 已定義的終結符 ID
tUnion[index] = stype;
}
else
{ // 未定義的非終結符ID
index=isinVns(lex.strval);
if( -1 == index )
{
index=insert_Vns(lex.strval,stype);
// nontUnion.push_back(stype);
}
else
{
nontUnion[index-STARTNONT]=stype;
}
}
}
match(Lex::ID);
}// while()
}
//rules : ID ':' rbodys ';' rules
// | /* empty */
// ;
Void
Parse::rules()
{
register sint32 index;
string rlval; // the rule's left value.
while( Lex::ID == lookahead )
{
rlval=lex.strval;
match(Lex::ID);
if( ':' == lookahead )
{
/* 檢查 ID 是否屬于終結符集,是則錯誤
*/
if (isinVts(rlval)!=-1)
{
err_msg<<"終結符\""<<rlval<<"\"不能作為產生式左部.";
showErr();
}
index = isinVns(rlval);
if ( -1 == index )
index = insert_Vns(rlval,-1);
/****/
if ( S < STARTNONT )
S=index;
/****/
match(':');
assert ( index >= STARTNONT );
rbodys(index);
if(';'==lookahead)
match(';');
else
{
err_msg<<"規則定義缺少 ';' .";
showErr();
}
}
else
{ // 如果不匹配,則忽略剩余的符號直到下一個 ';'
err_msg<<"規則定義缺少 ':' .";
showErr();
while( ';' != lookahead &&
Lex::ENDOFFILE != lookahead)
{
match(lookahead);
}
if(Lex::ENDOFFILE == lookahead)
{
err_msg<<"非正常的文件結束.";
fatal();
}
match(';'); // read next symbol.
}// else
}// while
}
//rbodys: '|' rbody prec rbodys
// | ID rbody prec rbodys
// | ASC rbody prec rbodys
// | '{' rbody prec rbodys
// | PREC prec rbodys /* 處理由 %prec 指定優先級的空產生式.*/
// | ';' /* 處理分號前邊可能產生的空產生式*/
// ;
Void
Parse::rbodys(const sint32 rl_ID)
{
register Bool Continue=True;
register sint32 tLast; // 每個產生式的最后一個終結符.
register sint32 tPrecedence; // 通過 %prec 關鍵字指定的終結符.
sint32 thisruleno; // 產生式所在行.
sint32 assoc,precedence;
Bool FirstTime=True;
// 是否已經存在了動作.主要用于處理 %prec ID 前邊同時
// 進行動作說明時的沖突處理.
Bool IsHaveAct=False;
while(Continue)
{
vector<sint32> rule; //識別出的規則.
rule.push_back(rl_ID);
thisruleno = lex.lineno;
IsHaveAct = False ;
tLast = -1;
switch(lookahead)
{
case '|':
if(True==FirstTime)
{ // expr : | ;
insert_ruler(rule,0,0,thisruleno);
}
match('|');
thisruleno=lex.lineno;
//break;
case Lex::ID:
case Lex::ASC:
case '{':
tLast=rbody(rule,IsHaveAct);
case Lex::PREC:
FirstTime=False;
tPrecedence=prec(rule,IsHaveAct);
if( -1 == tLast )
{ //
assoc=0;
precedence=0;
}
else
{ // 將終結符 tLast 的優先級與結合率轉移給產生式.
assoc=tAssoc[tLast];
precedence =tPrec [tLast];
}
if( -1 != tPrecedence )
{ // 如果存在 %prec 指定產生的優先級.
// assoc=tAssoc[tPrecedence];
precedence =tPrec [tPrecedence];
}
if( !IsHaveAct )
{
/*
* 如果產生沒有定義動作,在這里進行相應的處理.
*/
}
insert_ruler(rule,precedence,assoc,thisruleno);
if( ';'==lookahead )
return;
break;
case ';': // 正常結束.
assert(rule.size()==1);
// 插入此空產生式.
insert_ruler(rule,0,0,thisruleno);
//Continue=False;
return ;
default:
//err_msg<<"在規則定義中使用了不正確的符號 "<<lex.strval.c_str()<<" .";
//fatal();
//match(lookahead);// read next token.
Continue=False;
break;
}// switch
}// while
}
//rbody : /* empty */
// | ID rbody
// | ASC rbody
// | '{' eat_act '}' /* common action*/
// | '{' eat_act '}' ID rbody /* panel action */
// | '{' eat_act '}' ASC rbody /* panel action */
// | '{' eat_act '}' '{' rbody /* panel action */
// ;
sint32
Parse::rbody(vector<sint32> &cur_rule,Bool &IsHaveAct)
{ // 如果不存在終結符則返回 -1.
static sint32 panel_act_num=1;
sint32 index;
sint32 tLast=-1;
register Bool Continue=True;
// cur_rule.resize(1); // cur_rule[0] 已經存放產生式的左部.
IsHaveAct=False;
while(Continue)
{
switch(lookahead)
{
case Lex::ID:
index=isinVts(lex.strval);
if(-1 == index )
{// 如果不是終結符.
index=isinVns(lex.strval);
if(-1 == index) // 并且不在非終結符集中.
index=insert_Vns(lex.strval,-1); // 則插入.
}
else
{
tLast=index;
}
cur_rule.push_back(index);
match(Lex::ID);
break;
case Lex::ASC: // !!!! '\188' '\295' '\x33' 等進行check.
index=isinVts(lex.strval);
if( -1 == index )
{
//index=insert_Vts(lex.strval,0,0,-1,-1);
index=insert_Vts(lex.strval,0,0,-1,lex.numval);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -