先来实验指导书:
一、实验任务
设计、编制并调试一个中缀表达转换为后缀表达的实验程序,加深对词法分析、语法分析、语义分析及代码生成的理解。
二、 实验内容
1、词法
输入:扩展ASCII码字符集字符。除大小写26英文字母(letter)和数字0-9(digit)以及+ - * / ^ = ; , ( )以外,所有其他字符一律按等同于空格处理,一般用来分隔单词。
输出:识别单词,单词包括关键字、运算符、界符、标识符和整型常数。
(1)关键字:var
(2)运算符和界符:+ - * / ^ = ; , ( )
其中:乘除运算符(*, /)返回具有不同属性值的单词mulop,
加减运算符(+, -)返回具有不同属性值的单词addop。?
(3)标识符(id)和整型常数(num):
标识符(id)和整型常数(num)最大长度为8个字符,定义如下。
id = letter (letter | digit)* //以字母打头字母和数字组成的符号串
num = digit digit*//整形常数必须大于等于一位
2、语法(主要!!)
根据输入的单词序列,分析是否符合语法规则,如果不符合,应指明位置与理由;如果符合,则执行相应的语义子程序完成语义分析及中缀表达转换为后缀表达的过程。需注意的是,这里给出的是二义文法,从语义上考虑,表达式的计算按先幂次运算(^),再乘除运算(*, /)的 最后加减运算(+, - )的优先顺序; 括号((, ))用于调整运算先后顺序,既括号内部分先计算;赋值运算(=)最后进行。本实验系统的语法规则是:
program → compound
复合功能
compound → declaration assignstatement compound | ε
定义 赋值
declaration → var identifier_list ; | ε
定义 标识符
dentifier_list → id , dentifier_list | id
标识符中间可以有逗号相隔
assignstatement → id = expression ; | ε
词句 必须有赋值号
expression → expression addop expression |
加号两侧必须有单词
expression mulop expression |
乘号两侧必须有单词
expression ^ expression |
幂两侧必须有单词
( expression ) |
括号中间必须有单词
id | num
3、语义分析及代码生成
语义分析的主要任务是判断变量是否先定义后使用(只有这一个)。代码生成的的主要任务是将赋值语句从中缀表达转换为后缀表达。
三、 实验示例
示例1:
输入:
var a,b;
a = 10;
b = 5;
var x;
x = a + ( 25 * b ) ^ 2;
输出:
a 10 =
b 5 =
x a 25 b * 2 ^ + =
示例2:
输入:
var a;
a = 10;
b = 5;
var x;
x = a + ( 25 * b ^ 2;
输出:
第3行错误: 变量b未定义。
第5行错误: 缺右括号。
这坨代码全程都是压力比较大的情况下敲完的,哎挺简单的实验被我敲了350多行,还是能力不足,应该想出更好的方法。首先用逆波兰解决掉中缀转后缀,然后就是错误处理了。他这里不满足所有语法的都算错误吧,分为词法语法和语义,前前后后共找出17种错误,后来比较麻烦转化成signal数组检错,处理这些错误画了好多时间,一百多行的代码变成300多行。。
这里我模拟的是解释程序,老师后来让改翻译程序,改了的有点难看,这里就贴出解释程序:
附测试数据:
6
5
var a,b;
a = 10;
b = 5;
var x;
x = a + ( 25 * b ) ^ 2;
5
var a;
a = 10;
b = 5;
var x;
x = a + ( 25 * b ^ 2;
2
3 = 1 + 2;
3 = 1 & 2;
7
var apple666,banana,fffffffff,ff,0ccc,666p,1234;
banana = ( apple666 + 3 ) * 2;
ff = ( apple666 + 333333333 ) * 2;
banana = ( apple666 + 3 ) * 2
var a,b c d;
var banana;
9 + ( 3 - 1) * 3 + 10 / 2 = ;
13
var x;
x = 9 + ( 3 - 1) * 3 + 10 / 2;
x = 999999999 + 1;
x = 9 + ( 3 - 1) * + / 2;
x = 9 + ( 3 - 1) * - / 2;
x = 9 + ( 3 - 1) + * / 2;
x = 9 + ( 3 - 1) * 3 + / ;
x = 9 + ( 3 - 1) * 3 + ^ ;
x = 9 + ( - ) * 3 + 10 / 2;
x = 9 + ( ) * 3 + 10 / 2;
x = 9 + ( 3 - 1) * 3 + 10 2;
x = 9 + (((( 3 - 1 ) * 3 + 10 / 2;
x = 9 + ( 3 - 1 )))))) * 3 &