随笔-91  评论-137  文章-0  trackbacks-0
 
首先生成抽象语法树,方法如下:
1.根节点为0时表示没有default标签,为1时表示有default标签
2.第0个根节点表示switch里的条件
3.若有default标签,则最后一个根节点为default子树
4.每个根节点为0时表示在此标签下没有stmt_list语句块,这个节点的唯一孩子为要匹配的表达式;为1时表示有语句块,根节点的左孩子表示要匹配的表达式,右孩子为要执行的语句块
注意:Equal指令会弹出两操作数,应此在Equal指令执行之前必须先保留switch里exp的副本(即Push一次),最后弹出副本
测试代码:
 1 integer aaa,bbb
 2 
 3 function ccc()
 4     switch aaa + 1 do
 5         default:
 6             aaa = 123
 7         case 123:
 8             do
 9                 aaa = aaa + 1
10             while aaa < 789 end
11         case 456:
12             aaa = 123
13     end switch
14 end function
生成虚拟机代码:
posted @ 2010-09-29 15:55 lwch 阅读(1271) | 评论 (0)编辑 收藏
For语句的翻译比较复杂,有3个前置条件和运行代码,1个语句块,也就有4*3*2*1=24种情况.应此在生成抽象语法树的时候我采用的是2进制位来表示当前块是否存在,其中最底位表示stmt_list语句块,倒数第2位表示by之后的语句是否存在,倒数第3位表示to之后的表达式是否存在,倒数第4位表示for之后的语句是否存在.
代码:
 1 integer aaa,bbb
 2 
 3 function ccc()
 4     do
 5         for aaa = 456 to by do
 6             if aaa == 456 then
 7                 aaa = 789
 8             end if
 9         next
10         aaa = 123
11     while aaa == 123 end
12 end function
翻译结果:
posted @ 2010-09-22 12:20 lwch 阅读(1597) | 评论 (0)编辑 收藏
已实现do,while,if和赋值语句的语法制导翻译,这次将他们逐层嵌套起来看看翻译结果是否正确.
代码:
 1 integer aaa
 2 
 3 function ccc()
 4     while aaa == 123 do
 5         do
 6             if aaa == 123 then
 7                 if aaa == 456 then aaa = 123
 8                 else aaa = 456
 9                 end if
10             end if
11         while aaa == 123 end
12     end while
13     aaa = 456
14 end function
翻译结果:
posted @ 2010-09-20 22:29 lwch 阅读(1569) | 评论 (2)编辑 收藏
1 integer aaa
2 
3 function ccc()
4     if aaa and true then
5     end if
6 end function



1 integer aaa
2 
3 function ccc()
4     if aaa and true then
5         aaa = 123
6     end if
7 end function



1 integer aaa
2 
3 function ccc()
4     if aaa and true then
5     else
6     end if
7 end function



1 integer aaa
2 
3 function ccc()
4     if aaa and true then
5         aaa = 123
6     else
7     end if
8 end function



1 integer aaa
2 
3 function ccc()
4     if aaa and true then
5     else
6         aaa = 123
7     end if
8 end function



1 integer aaa
2 
3 function ccc()
4     if aaa and true then
5         aaa = 123
6     else
7         aaa = 456
8     end if
9 end function

posted @ 2010-09-19 07:27 lwch 阅读(1620) | 评论 (0)编辑 收藏
首先生成抽象语法树(AST)
生成方法:
1.移进时将Number,String或Symbol分别加入对应集合
2.归约时从集合中取出对应的成员,并删除这条产生式里的所有终结符
3.将产生的语法树节点压入栈中
4.当遇到产生式item_list->item_list item或stmt_list->stmt_list stmt时从栈中弹出两颗语法树并按顺序连接起来
5.当遇到非终结符时弹出相应数量的语法树节点,生成新的根节点并把弹出的语法树节点都连接到这个新的根节点上
6.当归约到第0条产生式时检查栈的元素数量,1为正常值,然后对抽象语法树进行前序遍历并生成虚拟机代码

posted @ 2010-09-17 22:21 lwch 阅读(737) | 评论 (0)编辑 收藏
     摘要:   1 %token "function" "as" "end";  2 %token "integer" "string" "bool" "pointer";  3 %token "if" "then" "e...  阅读全文
posted @ 2010-09-17 22:04 lwch 阅读(1054) | 评论 (0)编辑 收藏
输入文件:
 1 string abc,def;
 2 
 3 void main()
 4 {
 5     int abc,def;
 6     read(abc);
 7     write(abc);
 8     write("aaa");
 9 }
10 
11 void aaa()
12 {
13     int abc;
14 }
15 
16 int ddd,fff;

生成虚拟机代码为:


赋值语句逻辑比较复杂还未完成..
posted @ 2010-09-01 16:09 lwch 阅读(1406) | 评论 (0)编辑 收藏

分析文件:

 1 string abc;
 2 
 3 void main()
 4 {
 5     int a,b,c;
 6     read(a);
 7     write("aaa");
 8     write(a);
 9     b = 10;
10     c = 100;
11 }
12 
13 int cc()
14 {
15 }

结果:


下面的工作则是大量的语义处理...
posted @ 2010-08-31 23:27 lwch 阅读(617) | 评论 (0)编辑 收藏

分析器文法:

 1 %token    "%token" "%start"                ;
 2 %token    ";" "->" "|"                    ;
 3 
 4 %start program                        ;
 5 
 6 program        ->    item_list
 7         ;
 8 
 9 item_list    ->    item_list item
10         |    item
11         ;
12 
13 item        ->    token_def ";"
14         |    start_def ";"
15         |    rule_def ";"
16         |    ";"
17         ;
18 
19 token_def    ->    token_def "{String}"
20         |    "%token" "{String}"
21         ;
22 
23 start_def    ->    "%start" "{Symbol}"
24         ;
25 
26 rule_def    ->    "{Symbol}" "->" rhs_list
27         ;
28 
29 rhs_list    ->    rhs_list "|" rhs
30         |    rhs
31         ;
32 
33 rhs        ->    rhs "{String}"
34         |    rhs "{Symbol}"
35         |    "{String}"
36         |    "{Symbol}"
37         ;
38 
NScriptMacro
主要用来将给定的文法文件转化为LALR(1)分析表,生成的cpp和h文件可使用分析器分析,out文件是语法分析表
里面有个简单的CMinus的例子
posted @ 2010-08-30 17:29 lwch 阅读(1479) | 评论 (1)编辑 收藏
对于给定文法文件:
 1 %token "if" "then" "else" "end" ;
 2 %token "st" ;
 3 %token "+" "*" ;
 4 
 5 %start program ;
 6 
 7 program        ->    if_stmt
 8         ;
 9 
10 if_stmt        ->    "if" exp "then" stmt "end"
11         |    "if" exp "then" stmt "else" stmt "end"
12         ;
13 
14 exp        ->    exp1
15         ;
16 
17 exp1        ->    exp1 "+" exp2
18         |    exp2
19         ;
20 
21 exp2        ->    exp2 "*" exp3
22         |    exp3
23         ;
24 
25 exp3        ->    "{LQ}" exp1 "{RQ}"
26         |    "{digit}"
27         ;
28 
29 stmt        ->    "st"
30         ;
生成分析表得:
posted @ 2010-08-28 15:28 lwch 阅读(267) | 评论 (0)编辑 收藏
 1 %token    "%token" "%start"                ;
 2 %token    ";" "->" "|"                    ;
 3 
 4 %start program                        ;
 5 
 6 program        ->    item_list
 7         ;
 8 
 9 item_list    ->    item_list item
10         |    item
11         ;
12 
13 item        ->    token_def ";"
14         |    start_def ";"
15         |    rule_def ";"
16         |    ";"
17         ;
18 
19 token_def    ->    token_def "{String}"
20         |    "%token" "{String}"
21         ;
22 
23 start_def    ->    "%start" "{Symbol}"
24         ;
25 
26 rule_def    ->    "{Symbol}" "->" rhs_list
27         ;
28 
29 rhs_list    ->    rhs_list "|" rhs
30         |    rhs
31         ;
32 
33 rhs        ->    rhs "{String}"
34         |    rhs "{Symbol}"
35         |    "{String}"
36         |    "{Symbol}"
37         ;
38 
去除了letter定义,暂时还不支持正则表达式..
posted @ 2010-08-28 15:23 lwch 阅读(212) | 评论 (0)编辑 收藏
  1 #include <iostream>
  2 
  3 template <typename _Type>
  4 class HashTable
  5 {
  6 public:
  7     HashTable(int Length)
  8     {
  9         Element = new _Type[Length];
 10         for(int i=0;i<Length;i++)
 11             Element[i] = -1;
 12         this->Length = Length;
 13         Count = 0;
 14     }
 15     
 16     ~HashTable()
 17     {
 18         delete[] Element;
 19     }
 20     
 21     // Hash函数
 22     virtual int Hash(_Type Data)
 23     {
 24         return Data % Length;
 25     }
 26     
 27     // 再散列法
 28     virtual int ReHash(int Index,int Count)
 29     {
 30         return (Index + Count) % Length;
 31     }
 32     
 33     // 查找某个元素是否在表中
 34     virtual bool SerachHash(_Type Data,int& Index)
 35     {
 36         Index = Hash(Data);
 37         int Count = 0;
 38         while(Element[Index] != -1 && Element[Index] != Data)
 39             Index = ReHash(Index,++Count);
 40         return Data == Element[Index] ? true : false;
 41     }
 42     
 43     virtual int SerachHash(_Type Data)
 44     {
 45         int Index = 0;
 46         if(SerachHash(Data,Index)) return Index;
 47         else return -1;
 48     }
 49     
 50     // 插入元素
 51     bool InsertHash(_Type Data)
 52     {
 53         int Index = 0;
 54         if(Count < Length && !SerachHash(Data,Index))
 55         {
 56             Element[Index] = Data;
 57             Count++;
 58             return true;
 59         }
 60         return false;
 61     }
 62     
 63     // 设置Hash表长度
 64     void SetLength(int Length)
 65     {
 66         delete[] Element;
 67         Element = new _Type[Length];
 68         for(int i=0;i<Length;i++)
 69             Element[i] = -1;
 70         this->Length = Length;
 71     }
 72     
 73     // 删除某个元素
 74     void Remove(_Type Data)
 75     {
 76         int Index = SerachHash(Data);
 77         if(Index != -1)
 78         {
 79             Element[Index] = -1;
 80             Count--;
 81         }
 82     }
 83     
 84     // 删除所有元素
 85     void RemoveAll()
 86     {
 87         for(int i=0;i<Length;i++)
 88             Element[i] = -1;
 89         Count = 0;
 90     }
 91     
 92     void Print()
 93     {
 94         for(int i=0;i<Length;i++)
 95             printf("%d ",Element[i]);
 96         printf("\n");
 97     }
 98 protected:
 99     _Type* Element;        // Hash表
100     int Length;                // Hash表大小
101     int Count;                // Hash表当前大小
102 };
103 
104 void main()
105 {
106     HashTable<int> H(10);
107     printf("Hash Length(10) Test:\n");
108     int Array[6= {49,38,65,97,13,49};
109     for(int i=0;i<6;i++)
110         printf("%d\n",H.InsertHash(Array[i]));
111     H.Print();
112     printf("Find(97):%d\n",H.SerachHash(97));
113     printf("Find(49):%d\n",H.SerachHash(49));
114     H.RemoveAll();
115     H.SetLength(30);
116     printf("Hash Length(30) Test:\n");
117     for(int i=0;i<6;i++)
118         printf("%d\n",H.InsertHash(Array[i]));
119     H.Print();
120     printf("Find(97):%d\n",H.SerachHash(97));
121     printf("Find(49):%d\n",H.SerachHash(49));
122     system("pause");
123 }


运行结果:


由上图可知给定的Hash表长度越长越不容易产生冲突,性能也就越高.

posted @ 2010-08-10 23:37 lwch 阅读(545) | 评论 (1)编辑 收藏

基本语法:

 1 %token    "%token" "%letter" "%start"            ;
 2 %token    ":" ";" "->" "|"                ;
 3 
 4 %letter string    :    "{string}"            ;
 5 %letter symbol    :    "{symbol}"            ;
 6 
 7 %start program                        ;
 8 
 9 string_list    ->    string_list string
10         |    string
11         ;
12 
13 symbol_list    ->    symbol_list symbol
14         |    symbol
15         ;
16 
17 program        ->    item_list
18         ;
19 
20 item_list    ->    item_list item
21         |    item
22         ;
23 
24 item        ->    token_def ";"
25         |    letter_def ";"
26         |    start_def ";"
27         |    rule_def ";"
28         |    ";"
29         ;
30 
31 token_def    ->    "%token" string_list
32         ;
33 
34 letter_def    ->    "%letter" symbol ":" string_list
35         ;
36 
37 start_def    ->    "%start" symbol
38         ;
39 
40 rule_def    ->    symbol "->" rhs_list
41         ;
42 
43 rhs_list    ->    rhs_list "|" rhs
44         |    rhs
45         ;
46 
47 rhs        ->    term_list
48         ;
49 
50 term_list    ->    term_list string
51         |    term_list symbol
52         |    string
53         |    symbol
54         ;


生成的分析表:
由于状态数量和非终结符数量过多,所以给出文件《分析表》

下面是四则混合运算的文法文件:
 1 %token "+" "-"                ;
 2 %token "*" "/"                ;
 3 %token "(" ")"                ;
 4 
 5 %letter AddOp    :    "+" "-"        ;
 6 %letter MulOp    :    "*" "/"        ;
 7 %letter ID    :    "{digit}"    ;
 8 %letter LQ    :    "("        ;
 9 %letter RQ    :    ")"        ;
10 
11 %start Program                ;
12 
13 Program        ->    Exp
14         ;
15 
16 Exp        ->    Exp AddOp Term
17         |    Term
18         ;
19 
20 Term        ->    Term MulOp Factor
21         |    Factor
22         ;
23 
24 Factor        ->    LQ Exp RQ
25         |    ID
26         ;
posted @ 2010-08-03 20:21 lwch 阅读(281) | 评论 (0)编辑 收藏
对于给定表达式:
123 * 567 + 456 * (789 + 456)
生成四元码得:


对于表达式:
123 + 456 * (789 + 456) / 123 + 789
生成四元码得:
posted @ 2010-08-01 01:05 lwch 阅读(424) | 评论 (0)编辑 收藏
对于式子:10 + (5 + 9) / 3 - 7 * 3
求解过程如下:
 

主要在规约过程中增加了调用相关语义处理函数来实现计算.
posted @ 2010-07-26 11:41 lwch 阅读(359) | 评论 (0)编辑 收藏
仅列出标题
共7页: 1 2 3 4 5 6 7