软件构造编译原理程序自动生成First和Follow集
2017-12-23 22:54
549 查看
…最近快期末, 忙于考试和整理各种实验, 好久没有写博客了. 今天来补上一篇今天刚写完的实验. 本代码采用Node.js, 但逻辑看会了, 用C/C++改不是问题, 主要使用递归. 下面见如下代码
//主文件入口 index.js const readline = require('readline'); const fs = require('fs'); const path = require('path'); const anylize = require('./anylaze').anylize; const output = require('./output').output; const rl = readline.createInterface({ input: process.stdin, output: process.stdout, prompt: 'xuan >', }); rl.prompt(); let wenG = {}; let p = {}; rl.on('line', (line) => { let command = line.trim().split(/\s+/); if (command[0] == 'xuan') { let fileName = path.resolve(__dirname, command[1]); fs.exists(fileName, function (exists) { if (exists) { fs.readFile(fileName, 'utf-8', function (error, content) {//打开文件 if (error) { console.log(`打开文件失败${fileName}`); rl.prompt(); } else { let arr = content.split(/\s+/); for (let i = 0, length = arr.length; i < length; i++) { let str = arr[i].split('->'); if (wenG[str[0]] == undefined) { wenG[str[0]] = new Array(); p[str[0]] = new Object(); wenG[str[0]].push(str[1]); } else { wenG[str[0]].push(str[1]); } } console.log(wenG); console.log(" "); anylize(p, wenG); console.log(p); rl.prompt(); } }) } else { console.log(`文件不存在${fileName}`); rl.prompt(); } }) } else if (command[0] == 'start') { if (!wenG) { console.log('未选择文法文件'); rl.prompt(); } let left = "#E".split(""); let middle = command[1].split(""); let index = 1; output(index, p, left, middle); rl.prompt(); } rl.prompt(); }).on('close', () => { console.log('再见!'); process.exit(0); })
//核心算法 anylize.js 递归生成First和Follow集 function diguiFirst(prop, i, params, result, grammer) { let str; if (grammer[result[0]] == undefined) { params[prop][result[0]] = grammer[prop][i]; return; } else { for (let j = 0; j < grammer[result[0]].length; j++) { let a = result; a = grammer[result[0]][j] + result.substring(1); diguiFirst(prop, i, params, a, grammer); } } return; } function diguiFollow(prop, result, params, grammer, arr = new Array()) { result = result.replace('$', ''); let index = result.indexOf(prop); if (index != result.length - 1) {//递归结束条件 if (grammer[result[index + 1]] == undefined) { params[prop][result[index + 1]] = '$'; return; } } for (let i = 0; i < result.length; i++) { if ((grammer[result[i]] != undefined) && (!arr.includes(result[i])) && (result[i] != prop)) { arr.push(result[i]); let str; for (let j = 0; j < grammer[result[i]].length; j++) { str = result.substring(0, i) + grammer[result[i]][j] + result.substring(i + 1); diguiFollow(prop, str, params, grammer, arr); } } } return; } function Follow(prop, params, grammer) { for (let i = 0; i < grammer[prop].length; i++) { if (grammer[prop][i] == '$') { return; } diguiFollow(prop, grammer[prop][i], params, grammer); //遍历所有项 } } function anylize(params, grammer) { for (let prop in grammer) { for (let i = 0; i < grammer[prop].length; i++) { let str = ''; if (grammer[prop][i] != '$') { str += 'first ' + grammer[prop][i]; console.log(str); diguiFirst(prop, i, params, grammer[prop][i], grammer); } else { str += 'follow ' + prop; console.log(str); params[prop]['#'] = '$'; Follow(prop, params, grammer); } } } } module.exports = { anylize }
//输出 output.js 输出文件 function output(index, params, left, middle) { if (middle.length == 0) { return ; } let str; if (left[left.length - 1] == middle[0]) { str = middle[0] + " 匹配"; console.log(`${index++}\t${left.join("")}\t\t${middle.join("")}\t\t${str}`); left.pop(); middle.shift(); } else { str = params[left[left.length - 1]][middle[0]]; console.log(`${index++}\t${left.join("")}\t\t${middle.join("")}\t\t${left[left.length - 1]}->${str}`); if (str == "$") { str = ""; left.pop();//弹出最后一个值 } else { str = str.split(""); left.pop(); for (let i = str.length - 1; i >= 0; i--) { left.push(str[i]); } } } output(index, params, left, middle); } module.exports.output = output;
相关文章推荐
- 软件工程第一个程序:像阿超那样,花20分钟写一个能自动生成小学四则运算题目的 “软件”,要求:除了整数以外,还要支持真分数的四则运算。
- 编译原理-用Bison构造语法分析程序-二进制转换十进制
- MFC:“Debug Assertion Failed!” ——自动生成的单文档程序项目编译运行就有错误
- 【编译原理】使用flex生成词法扫描程序步骤
- 学习使用AutoMake1.9的自动生成工程文件(二)——flat型程序编译实践过程
- 【编译原理】语法分析LL(1)分析法的FIRST和FOLLOW集
- [版本构造]给delphi生成的软件增加版本信息 续---编译乱码问题解决
- MFC:“Debug Assertion Failed!” ——自动生成的单文档程序项目编译运行就有错误
- 编译原理与编译构造 预测分析程序的构造
- 微信小程序前端自动生成工具,附软件使用视频
- MFC:“Debug Assertion Failed!” ——自动生成的单文档程序项目编译运行就有错误
- 软工第一个程序:像二柱子那样,花二十分钟写一个能自动生成小学四则运算题目的 “软件”,要求:除了整数以外,还要支持真分数的四则运算。
- c++程序编译后自动生成的文件有什么用
- c++程序编译后自动生成的文件有什么用
- 软件工程第二个程序:“像阿超那样,花20分钟写一个能自动生成小学四则运算题目的 ‘软件’”的功能扩充
- 微信小程序自动切片生成布局软件的用法
- 编译原理学习笔记05——(识别孙悟空72变之魔鬼特训—递归下降分析程序构造)——2014_1_20
- 微信小程序自动切片生成布局软件
- 编译原理 实验1 词法分析程序的构造
- 南燕新闻自动生成软件——scrapy爬虫程序