您的位置:首页 > 其它

哈工大编译原理实验2——语法分析

2016-03-05 15:18 351 查看
此次试验由于指导书的文法比较简单,且没有消除左递归(我懒),因此使用学长的文法,并加上了数组判断。

S -> func funcs
funcs -> func funcs
funcs -> $
func -> type IDN ( args ) func_body
type -> int
type -> short
type -> long
type -> char
type -> float
type -> double
type -> void
type -> unsigned type
args -> type IDN arg
args -> $
arg -> , type IDN arg
arg -> $
func_body -> ;
func_body -> block
block -> { define_stmts stmts }
define_stmts -> define_stmt define_stmts
define_stmts -> $
define_stmt -> type IDN init vars ;
init -> = expression
init -> [ INT10 ]
init -> $
vars -> , IDN init vars
vars -> $
stmts -> stmt stmts
stmts -> $
stmt -> assign_stmt
stmt -> jump_stmt
stmt -> iteration_stmt
stmt -> branch_stmt
assign_stmt -> expression ;
jump_stmt -> continue ;
jump_stmt -> break ;
jump_stmt -> return isnull_expr ;
iteration_stmt -> while ( logical_expression ) block_stmt
iteration_stmt -> for ( isnull_expr ; isnull_expr ; isnull_expr ) block_stmt
iteration_stmt -> do block_stmt while ( logical_expression ) ;
branch_stmt -> if ( logical_expression ) block_stmt result
result -> else block_stmt
result -> $
logical_expression -> ! expression bool_expression
logical_expression -> expression bool_expression
bool_expression -> lop expression bool_expression
bool_expression -> $
lop -> &&
lop -> ||
branch_stmt -> switch ( IDN ) { case_stmt case_stmts default_stmt }
case_stmts -> case_stmt case_stmts
case_stmts -> $
case_stmt -> case const : stmts
default_stmt -> default : stmts
block_stmt -> { stmts }
isnull_expr -> expression
isnull_expr -> $
expression -> value operation
operation -> compare_op value
operation -> equal_op value
operation -> $
compare_op -> >
compare_op -> >=
compare_op -> <
compare_op -> <=
compare_op -> ==
compare_op -> !=
equal_op -> =
equal_op -> +=
equal_op -> -=
equal_op -> *=
equal_op -> /=
equal_op -> %=
value -> item value'
value' -> + item value'
value' -> - item value'
value' -> $
item -> factor item'
item' -> * factor item'
item' -> / factor item'
item' -> % factor item'
item' -> $
factor -> ( value )
factor -> IDN call_func
factor -> const
call_func -> ( es )
call_func -> $
es -> isnull_expr isnull_es
isnull_es -> , isnull_expr isnull_es
isnull_es -> $
const -> num_const
const -> FLOAT
const -> CHAR
const -> STR
num_const -> INT10
num_const -> INT8
num_const -> INT16
//获取First集
public void getFirst(){
//终结符全部求出first集
ArrayList<String> first;
//求出所有终结符的First集
for (int i = 0; i < terminals.size(); i++) {
first = new ArrayList<String>();
first.add(terminals.get(i));
firsts.put(terminals.get(i), first);
}

//给所有非终结符注册一下
for (int i = 0; i < nonterminals.size(); i++) {
first = new ArrayList<String>();
firsts.put(nonterminals.get(i), first);
}

boolean flag;
while (true) {
flag = true;
String left;
String right;
String[] rights;
for (int i = 0; i < productions.size(); i++) {
//遍历每一个产生式
left = productions.get(i).returnLeft();
rights = productions.get(i).returnRights();
for (int j = 0; j < rights.length; j++) {
//遍历每个产生式右部的每个元素
right = rights[j];
//right是否存在,遇到空怎么办
//如果right不为空
if(!right.equals("$")) {
for (int l = 0; l < firsts.get(right).size(); l++) {
if(firsts.get(left).contains(firsts.get(right).get(l))){
continue;
}
else {
firsts.get(left).add(firsts.get(right).get(l));
flag=false;
}
}
}
//如果右部可以为空
if (isCanBeNull(right)) {
continue;
}
else {
break;
}
}
}
if (flag == true) {
break;
}
}
//非终结符的first集
}

//判断是否产生$
public boolean isCanBeNull(String symbol) {
String[] rights;
for (int i = 0; i < productions.size(); i++) {
//找到产生式
if (productions.get(i).returnLeft().equals(symbol)) {
rights = productions.get(i).returnRights();
if (rights[0].equals("$")) {
return true;
}
}
}
return false;
}
//获得Follow集
public void getFollow() {
//所有非终结符的follow集初始化一下
ArrayList<String> follow;
for (int i = 0; i < nonterminals.size(); i++) {
follow = new ArrayList<String>();
follows.put(nonterminals.get(i), follow);
}
//将#加入到follow(S)中
follows.get("S").add("#");

boolean flag;
boolean fab;
while (true) {
flag = true;
//循环,遍历所有产生式
for (int i = 0; i < productions.size(); i++) {
String left;
String right;
String[] rights;
rights = productions.get(i).returnRights();
//遍历产生式右部
for (int j = 0; j < rights.length; j++) {
right = rights[j];

//非终结符
if (nonterminals.contains(right)) {
fab = true;
for(int k = j+1; k < rights.length; k++) {
//查找first集
for(int v = 0; v < firsts.get(rights[k]).size(); v++) {
//将后一个元素的first集加入到前一个元素的follow集中
if(follows.get(right).contains(firsts.get(rights[k]).get(v))) {
continue;
}
else {
follows.get(right).add(firsts.get(rights[k]).get(v));
flag=false;
}
}
if (isCanBeNull(rights[k])) {
continue;
}
else {
fab = false;
break;
}
}
//如果存在一个产生式A→αB,或存在产生式A→αBβ且FIRST(β) 包含ε,
//那么 FOLLOW(A)中的所有符号都在FOLLOW(B)中
if(fab) {
left = productions.get(i).returnLeft();
for (int p = 0; p < follows.get(left).size(); p++) {
if (follows.get(right).contains(follows.get(left).get(p))) {
continue;
}
else {
follows.get(right).add(follows.get(left).get(p));
flag = false;
}
}
}
}
}
}
//全部处理后跳出循环
if(flag==true){
break;
}
}
//清除follow集中的#
String left;
for (int j = 0; j < nonterminals.size(); j++) {
left = nonterminals.get(j);
for (int v=0; v<follows.get(left).size(); v++) {
if(follows.get(left).get(v).equals("#"))
follows.get(left).remove(v);
}
}
}
//获取Select集
public void getSelect() {
String left;
String right;
String[] rights;
ArrayList<String> follow = new ArrayList<String>();
ArrayList<String> first = new ArrayList<String>();

for (int i = 0; i < productions.size(); i++) {
left = productions.get(i).returnLeft();
rights = productions.get(i).returnRights();
if(rights[0].equals("$")) {
// select(i) = follow(A)
follow = follows.get(left);
for (int j = 0; j < follow.size(); j++) {
if(productions.get(i).select.contains(follow.get(j))){
continue;
}
else {
productions.get(i).select.add(follow.get(j));
}
}
}
//如果文法G的第i个产生式为A→aβ,则定义
//SELECT(i)={a}
else {
boolean flag = true;
for (int j = 0; j < rights.length; j++) {
right = rights[j];
first = firsts.get(right);
for (int v = 0; v < first.size(); v++) {
if (productions.get(i).select.contains(first.get(v))) {
continue;
}
else {
productions.get(i).select.add(first.get(v));
}
}
if(isCanBeNull(right)) {
continue;
}
else {
flag = false;
break;
}
}
//First集中有空
if (flag) {
follow = follows.get(left);
for (int j = 0; j < follow.size(); j++) {
if (productions.get(i).select.contains(follow.get(j))) {
continue;
}
else {
productions.get(i).select.add(follow.get(j));
}
}
}
}
}
}
//语法分析
public void Parsing() {
//遍历输入缓冲区
/*for(int i = 0; i < inputCache.size(); i++) {
System.out.println(inputCache.get(i));
}*/
//初始符号压入栈
stack.add("S");
String right;
String leftandinput;
String process="";
//当栈非空,输入缓冲区存在
while (stack.size()>0 && inputCache.size()>0 ) {
//输入缓冲区与推导符号串第一个字符相等的话,删掉
try {
if(inputCache.get(0).equals(stack.get(stack.size()-1))) {
inputCache.remove(0);
stack.remove(stack.size()-1);
continue;
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}

//匹配字符
leftandinput = stack.get(stack.size()-1)+"-"+inputCache.get(0);
//能够找到匹配的
if((right=predictMap.get(leftandinput))!=null) {
//输出产生式和推导过程
process = "";
for (int i = stack.size()-1; i>-1; i--) {
process = process + stack.get(i)+" ";
}
//输出
DefaultTableModel tableModel = (DefaultTableModel) jtable4.getModel();
tableModel.addRow(new Object[] {stack.get(stack.size()-1)+" -> "+right, process});
jtable4.invalidate();
//删掉产生的字符,压入堆栈
stack.remove(stack.size()-1);
if(right.equals("$")) {
//只弹不压
}
//压入后序字符
else {
String[] arg = right.split(" ");
for(int i = arg.length-1; i>-1; i--) {
//反向压入堆栈
stack.add(arg[i]);
}
}
}
//否则的话报错
else {
//重新书写process
process="";
for (int i = stack.size()-1; i>-1; i--) {
process = process + stack.get(i)+ " ";
}
//tbmodel_lex_result.addRow(new String[]{process, "ERROR!  无法识别的字符"+input_cache.get(0)+"产生式"+leftandinput});
DefaultTableModel tableModel = (DefaultTableModel) jtable2.getModel();
tableModel.addRow(new Object[] { "无法识别的字符:"+ inputCache.get(0),"产生式:"+leftandinput});
jtable4.invalidate();
inputCache.remove(0);
}
}
}




完整工程源代码:https://github.com/SalamanderJY/Compiler_Experiment
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编译原理