LR1語法分析C++實現:四、demo 2 加乘計算器-有語義函數

轉載請註明出處:https://blog.csdn.net/hhhhhhhhhhkkkkkkkkkk

demo 2 加乘計算器-有語義函數

#include<stdio.h>
#include"_lr1.h"
enum e_non
{
 e_entry=-0xffff,
 e_exp,
};
t_grammar g=
{
 {
  {e_entry,{e_exp},[](t_analyzer*ana) {ana->ref(0); },0},
  {e_exp,{e_exp,'+',e_exp},[](t_analyzer*ana) {ana->ret(ana->get<float>(0)+ana->get<float>(2)); },0},
  {e_exp,{e_exp,'*',e_exp},[](t_analyzer*ana) {ana->ret(ana->get<float>(0)*ana->get<float>(2)); },0},
  {e_exp,{'i'},[](t_analyzer*ana) {ana->ret(1.0f); },0},
 },
 {
  {'+',{1,e_ass_left}},
  {'*',{2,e_ass_left}},
  {'i',{3,e_ass_left}},
 },
 nullptr
};
int main(int argc, const char*argv[])
{
 grammar_make_pri_ass(g);
 print_grammar(g);
 auto cluster = cluster_build(g, 0);
 printf("---------------------\n");
 print_cluster(cluster, g.sens);
 printf("---------------------\n");
 t_analyzer ana;
 ana.analysis(std::vector<int>{ 'i','+','i','*','i',0 }, cluster, g, nullptr);
 getchar();
 return 0;
}

在這裏插入圖片描述在這裏插入圖片描述可以看到,在11-14行添加了語義函數後,能夠得到2.0這個 正確結果了(不要看最後一排結果,那裏已經塵歸塵,土歸土,什麼結果也沒有了)。
當然,爲了簡便,這裏的數字取的直接是1,如果想實現真正的數值計算,有兩個辦法:
1 如果只是單個數字,將

exp=i 

改成

exp=0
exp=1
... 
exp=9

2 如果是多位數,構造一個前端分析器(可以直接用手擼),將數字都轉成i,同時保存多位數在串中的範圍(其實這個就是爲什麼一般yacc之前還有一個lex的原因);

然後調用ana->range(0)得到當前輸入串的位置,再映射到上面保存的範圍,這樣可以從輸入串中讀取當前的終結符值,然後就可以轉成數字參與計算了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章