前言
之前的文章對(duì)于詞法分析和語(yǔ)法分析規(guī)則進(jìn)行了講解,我們的目標(biāo) 是解析代碼并生成語(yǔ)法樹(shù)阁簸,因此必須在識(shí)別出語(yǔ)句或表達(dá)式時(shí)添加生成語(yǔ)法樹(shù)的代碼.
為了達(dá)到上述目的,可以借助 action
功能,當(dāng) token
序列和語(yǔ)法規(guī)則匹配時(shí)就能夠執(zhí)行任意代碼.
本文將對(duì) action
的使用方法進(jìn)行說(shuō)明
action
可以通過(guò)在符號(hào)串內(nèi)部添加{ }
代碼塊,執(zhí)行我們想要添加的一些特點(diǎn)操作,這些代碼塊被稱為action,舉例
void defstruct(): {}
{
<STRUCT> name()
{
System.out.println(" 發(fā)現(xiàn)了結(jié)構(gòu)體!"); }
member_list()
{
System.out.println(" 發(fā)現(xiàn)了成員列表!"); }
";"
{
System.out.println(" 發(fā)現(xiàn)了分號(hào)!"); }
}
action的執(zhí)行時(shí)機(jī)
終端符號(hào)被執(zhí)行時(shí),才會(huì)觸發(fā)action,掃描終端符號(hào)不會(huì)觸發(fā)action
需要注意“解析終端符號(hào)”和“掃描終端符號(hào)”是不同的.解析器會(huì)對(duì) token
進(jìn)行超前掃描糕非,因此即便是寫(xiě)在 action
之后的 token
,也完全有可能已經(jīng)被掃描器讀取進(jìn)來(lái)了
例如下面的規(guī)則州丹,在 action 執(zhí)行時(shí) <X> 和 <Y> 就已經(jīng)被掃描進(jìn)來(lái)了
LOOKAHEAD(2) { System.out.println("action executed"); } <X> <Y>
但解析器一定會(huì)在執(zhí)行 action 之后再對(duì) <X> 和 <Y> 進(jìn)行解析
token類(lèi)的屬性
只需寫(xiě)“變量名 = 非終端符號(hào)”怜跑,就能獲取終端符號(hào)和非終端符號(hào)的語(yǔ)義值
語(yǔ)義值
我們可以設(shè)置返回語(yǔ)義值的action
String name():
{
Token tok;
}
{
tok=<IDENTIFIER> { return tok.image; }
}
action的執(zhí)行次數(shù)
選擇和action
: 如果在所有選項(xiàng)的最后執(zhí)行共通的action
{
Token x, y;
}
{
(x=<X> | y=<Y>)
{
if (x != null) {
System.out.println("X found. image=" + x.image);
}
else {
System.out.println("Y found. image=" + y.image);
}
}
}
重復(fù)和action
每當(dāng)發(fā)現(xiàn) <X> 和 <Y>時(shí)都會(huì)執(zhí)行
void iteration():
{
Token x, y;
}
{
(x=<X> y=<Y>
{
System.out.println("x=" + x.image + "; y=" + y.image);
} )*
}
只會(huì)執(zhí)行一次
void iteration2():
{
Token x, y;
}
{
(x=<X> y=<Y>)*
{
System.out.println("x=" + x.image + "; y=" + y.image);
}
}
總結(jié)
上面介紹了action
主要功能和獲取語(yǔ)義值,本文的總結(jié)如下
- 使用 action 能夠獲取終端符號(hào) / 非終端符號(hào)的語(yǔ)義值,還能夠給非終端符號(hào)賦予語(yǔ)義值
- 終端符號(hào)的語(yǔ)義值為 Token 類(lèi)的實(shí)例。從 Token 類(lèi)的屬性中可以取得 token 的字面量及其在源文件中的位置等信息
- 非終端符號(hào)的語(yǔ)義值取決于 action奔脐。通過(guò)在規(guī)則的開(kāi)頭添加語(yǔ)義值的類(lèi)型炸站,并從 action 返回值温兼,就可以設(shè)置語(yǔ)義值
- 當(dāng)解析到規(guī)則中寫(xiě)有 action 之處時(shí),action 才會(huì)被執(zhí)行武契。若在符號(hào)串的最后寫(xiě)有 action募判,那么在該符號(hào)串全部被發(fā)現(xiàn)后 action 才會(huì)被執(zhí)行
- 組合使用選項(xiàng)和 action,能夠編寫(xiě)只有在發(fā)現(xiàn)特定的選項(xiàng)時(shí)才被執(zhí)行的 action
- 組合使用重復(fù)和 action咒唆,能夠編寫(xiě)在每次重復(fù)時(shí)都會(huì)被執(zhí)行的 action