Parser
Parser 实验报告
目录
一、实验要求的正则表达式
(注:其中,黑色字体表示之前做的扫描器中已经实现的表达式,红色字体表示扫描器中没有实现或需要修改的表达式)
1 program -> declarations stmt-sequence
2 declarations -> decl ; declarations |ε
3 decl -> type-specifier varlist
4 type-specifier -> int | bool | string
5 varlist -> identifier { , identifier }
6 stmt-sequence -> statement { ; statement }
7 statement -> if-stmt | repeat-stmt | assign-stmt | read-stmt | write-stmt | while-stmt
8 while-stmt -> while bool-exp do stmt-sequence end
9 if-stmt -> if bool-exp then stmt-sequence [else stmt-sequence] end
10 repeat-stmt -> repeat stmt-sequence until bool-exp
11 assign-stmt -> identifier:=exp
12 read-stmt -> read identifier
13 write-stmt -> write exp
14 exp -> arithmetic-exp | bool-exp | string-exp
15 arithmetic-exp -> term { addop term }
16 addop -> + | -
17 term -> factor { mulop factor }
18 mulop -> * | /
19 factor -> (arithmetic-exp) | number | identifier
20 bool-exp -> bterm { or bterm }
21 bterm -> bfactor { and bfactor}
22 bfactor -> comparison-exp
23 comparison-exp -> arithmetic-exp comparison-op arithmetic-exp
24 comparison-op -> < | = | > | >= | <=
string-exp -> string
二、实验最终的表达式:
1、 program -> declarations stmt-sequence
2、 declarations -> {decl ;}
(由declarations -> decl ; declarations |ε变换得到)
3、 decl -> type-specifier identifier { , identifier }
(由decl -> type-specifier varlist 和 varlist -> identifier { , identifier }联合得到)
4、 stmt-sequence -> statement { ; statement}
5、 statement -> if-stmt | repeat-stmt | assign-stmt | read-stmt | write-stmt | while-stmt
6、 while-stmt -> while bool-exp do stmt-sequence end
7、 if-stmt -> if bool-exp then stmt-sequence [else stmt-sequence] end
8、 repeat-stmt -> repeat stmt-sequence until bool-exp
9、 assign-stmt -> identifier:=exp
10、 read-stmt -> read identifier
11、 write-stmt -> write exp
12、 exp -> STR | (arit_exp [bool_exp1])
13、 arit_exp -> term { (+|-) term }
14、 term -> factor { mulop factor }
15、 factor -> (arithmetic-exp) | number | identifier
16、 bool_exp -> arit_exp bool_exp1
17、 bool_exp1 -> bterm { OR arit_exp bterm }
18、 bterm -> bfactor { AND arit_exp bfactor }
19、 bfactor -> (LT|EQ|MT|MOT|LOT) arit_exp
三、实验说明:
1、变量声明
TreeNode * declarations(TreeNode ** p)中,变量采用链表的方法。p为链表的最末端节点,若插入一个节点q时,将其设为p的下一个节点,再将q赋给p。
实现正则表达式decl -> type-specifier identifier { , identifier }时,TreeNode * decl(void)中,类型为根节点,变量为其子节点。
例:
string str;
int x, fact;
代码的生成树为:
2、参数传递
实验要求的正则表达式中,以下六条存在左因子:
exp -> arithmetic-exp | bool-exp | string-exp
bool-exp -> bterm { or bterm }
bterm -> bfactor { and bfactor}
bfactor -> comparison-exp
comparison-exp -> arithmetic-exp comparison-op arithmetic-exp
comparison-op -> < | = | > | >= | <=
提取左因子后得到的正则表达式为:
exp -> string-exp | (arit_exp [bool_exp1])
bool_exp -> arit_exp bool_exp1
bool_exp1 -> bterm { OR arit_exp bterm }
bterm -> bfactor { AND arit_exp bfactor }
bfactor -> (LT|EQ|MT|MOT|LOT) arit_exp
本实验中采用了传参的方法。
exp -> arithmetic-exp | bool-exp | string-exp中,对bool-exp 和string-exp提取左因子得到exp -> STR | (arit_exp [bool_exp1])。根据token是否为arit_exp的first set来判断表达式是string 表达式还是arit表达式或bool表达式。如果是后一种情况,再读取下一个token。如果下一个token不是比较符号,则该表达式为arit表达式,不需要传参;否则,该表达式为bool表达式,那么,将bool表达式中最左边的第一个算术表达式作为参数传给子节点。
Bool表达式变换为bool_exp -> arit_exp bool_exp1。
TreeNode * bool_exp1(TreeNode * arit)
TreeNode * bterm(TreeNode * arit)
TreeNode * bfactor(TreeNode * arit)
这三个函数头中的参数从上往下层层传递。参数为exp -> STR | (arit_exp [bool_exp1])中的arit_exp ,也即bool表达式中最左边的第一个算术表达式,然后在bfactor函数内加入到树中作为子节点。
四、运行截图:
1、正常运行界面
2、若出现缺少右括号
如fact:=fact*(x+6+3*5; ,则出现下图:
3、若出现赋值符号:=写成=
如fact=1; ,则出现下图:
代码文档下载:
https://files.cnblogs.com/sandywong/Parser_by_Sandy.rar