package com.analysis4;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/**
*1.保留字
*2.运算符
*3.界符
*/
public class Demo {
public static int baoliuzi = 0;
public static int yunsuanfu = 0;
public static int biaoshifu = 0;
public static int jiefu = 0;
public static int elsewords = 0;
//将txt文件转为数组
public String txt2String(File file) throws IOException
{
StringBuilder result =new StringBuilder();
try {
BufferedReader br= new BufferedReader(new FileReader(file));
String s=null;
while((s=br.readLine())!=null){
result.append(System.lineSeparator()+s);
}
br.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result.toString();
}
//对文本进行预处理
public char[] preTreatment(char[] sourcefile)
{
char []afterfile = new char[10000];
int index=0;
if(sourcefile.length!=0)
{
for(int i=0;i='a'&&c<='z')||(c>='A'&&c<'Z'))
{
return true;
}
else
return false;
}
//判断是否为保留字,并返回编号
public int isReserve(String s,String []reserve)
{
int index=-1;
for(int i=0;i='0'&&c<='9')
{
return true;
}
else
return false;
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//保留字
String []reserve={"if","else","while","throw","this","int","String","char","double","float","this",
"static","public","private","default","switch","catch","void","try","return"};//0~99
//运算符
String []operator={"+","-","*","/","++","--","==","!=",">","<",">=",
"<=","&&","||","!","&","|","^","~","<<",">>",">>>","+=","="};//110~149
//界符
char []divide={'<','>','(',')','{','}','[',']','\'','"',',',';','?','/','\\',':','.'};//150~无穷
Demo la=new Demo();
//源代码的txt文件
File file=new File("D://1.txt");
//将txt格式的源文件放入sourcefile的字符数组中
String source=la.txt2String(file);
char sourcefile[] = source.toCharArray();
//将源代码进行预处理,去掉注释和换行符
char afterfile[]=la.preTreatment(sourcefile);
//index记录源代码的字符数组扫描到的数组下标
int index=0;
//temp用于存储临时的字符串
String temp="";
//当未扫描到终结符则一直往下扫描
while(afterfile[index]!='\0'){
//当开头为字母时,可能为保留字或是标识符
if(la.isLetter(afterfile[index]))
{
temp+=afterfile[index];
//当下一个字符不为字母或数字,则停止扫描,并将扫描结果存入temp
while(la.isLetter(afterfile[index+1])||la.isDigit(afterfile[index+1]))
{
index++;
temp+=afterfile[index];
}
//将temp与保留字数组匹配,匹配成功即为保留字,否则为标识符
if(la.isReserve(temp, reserve)!=-1) {
System.out.println("保留字:("+la.isReserve(temp, reserve)+","+temp+")");
baoliuzi++;
}
else {
System.out.println("标识符:("+100+","+temp+")");
biaoshifu++;
}
}
//当开头为数字时,可能为整数或小数
else if(la.isDigit(afterfile[index]))
{
temp+=afterfile[index];
while(la.isDigit(afterfile[index+1]))
{
index++;
temp+=afterfile[index];
}
//若在数字后有小数点,继续判断
if(afterfile[index+1]=='.')
{
index++;
//小数点后无数字,检测出错
if(!la.isDigit(afterfile[index+1])){
System.out.println("此处有误,小数点后无数字");
temp="";
break;
}
//小数点后有数字,检测为小数
else
{
temp+=afterfile[index];
while(la.isDigit(afterfile[index+1]))
{
index++;
temp+=afterfile[index];
}
}
System.out.println("小数常数:("+102+","+temp+")");
}
//无小数点,检测为整数
else
{
System.out.println("整数常数:("+100+","+temp+")");
}
}
//既不是数字也不是字母也不是空格,则为界符或运算符,跳过空格
else if(afterfile[index]!=' ')
{
temp+=afterfile[index];
/*由于界符只有一个字符长度,则temp放入一个字符后直接开始匹配界符数组,
* 匹配成功则continue循环,匹配失败则继续扫描
*/
if(la.isDivide(temp, divide)!=-1)
{
System.out.println("界符:("+la.isDivide(temp, divide)+","+temp+")");
temp="";
index++;
jiefu++;
continue;
}
//判断是否为运算符
else
{
//若下一个字符也是符号类型则加入temp
while((la.isDivide(afterfile[index+1]+"", divide)==-1)&&(la.isDigit(afterfile[index+1])==false)
&&(la.isLetter(afterfile[index+1])==false))
{
index++;
temp+=afterfile[index];
}
//与运算符数组匹配,匹配成功,则为运算符,失败,则可能出现了检测不了的字符。
if(la.isOperator(temp, operator)!=-1) {
System.out.println("运算符:("+la.isOperator(temp, operator)+","+temp+")");
yunsuanfu++;
}
else {
System.out.println(temp+"无法识别,可能为中文字符或者此字符暂未被收录......");
elsewords++;
}
}
}
temp="";
index++;
}
System.err.println("保留字的个数为:"+baoliuzi);
System.err.println("标识符的个数为"+biaoshifu);
System.err.println("界符的个数为"+jiefu);
}
}
//保留字 标识符 ( 运算符) 界符
//public class Demo{
// public static void main(String[] args){
// System.out.println(“Hello World!!!”);
// }
//}
package com.analysis3;
import java.util.Stack;
public class GramerAnasys {
//加入同步符号的LL(1)分析表
private String [][] analysisTable = new String[][]{
{"TZ","","","TZ","synch","synch"},
{"","+TZ","","","ε","ε"},
{"FY","synch","","FY","synch","synch"},
{"","ε","*FY","","ε","ε"},
{"i","synch","synch","(E)","synch","synch"}
};
//存储终结符
private String [] VT = new String[]{"i","+","*","(",")","#"};
//存储终结符
private String [] VN = new String[]{"E","Z","T","Y","F"};
//输入串
private StringBuilder strToken = new StringBuilder("i+i*i+i*i");
//分析栈
private Stack stack = new Stack();
//a保存从输入串中读取的一个输入符号,当前符号
private String a = null;
//X中保存stack栈顶符号
private String X = null;
//flag标志预测分析是否成功
private boolean flag = true;
//记录输入串中当前字符的位置
private int cur = 0;
//记录步数
private int count = 0;
//输出语法规则
protected void print(){
System.out.printf("E→TZ \n"+"Z→+TZ|ε \n"+"T→FY \n"+"Y→*FY|ε \n"+"F→(E)|i \n");
}
//初始化
protected void init(){
strToken.append("#");
stack.push("#");
System.out.printf("%-9s %-38s %6s %-20s\n","步骤 ","符号栈 "," 输入串 "," 所用产生式 ");
stack.push("E");
curCharacter();
System.out.printf("%-6d %-20s %6s \n",count,stack.toString(),strToken.substring(cur, strToken.length()));
}
//读取当前栈顶符号
protected String stackPeek(){
X = stack.peek();
return X;
}
//返回输入串中当前位置的字母
private String curCharacter(){
a = String.valueOf(strToken.charAt(cur));
return a;
}
//判断X是否是终结符
protected boolean XisVT(){
for(int i = 0 ; i < (VT.length - 1); i++){
if(VT[i].equals(X)){
return true;
}
}
return false;
}
//查找X在非终结符中分析表中的横坐标
protected String VNTI(){
int Ni = 0 , Tj = 0;
for(int i = 0 ; i < VN.length ; i++){
if(VN[i].equals(X)){
Ni = i;
}
}
for(int j = 0 ; j < VT.length ; j++){
if(VT[j].equals(a)){
Tj = j;
}
}
return analysisTable[Ni][Tj];
}
//判断M[A,a]={X->X1X2...Xk}
//把X1X2...Xk推进栈
//X1X2...Xk=ε,不推什么进栈
protected boolean productionType(){
if(VNTI() != ""){
return true;
}
return false;
}
//推进stack栈
protected void pushStack(){
stack.pop();
String M = VNTI();
String ch;
for(int i = (M.length() -1) ; i >= 0 ; i--){
ch = String.valueOf(M.charAt(i));
stack.push(ch);
}
System.out.printf("%-6d %-20s %6s %-1s->%-12s\n",(++count),stack.toString(),strToken.substring(cur, strToken.length()),X,M);
}
//总控程序
protected void totalControlProgram(){
while(flag == true){
stackPeek();
if(XisVT() == true){
if(X.equals(a)){
cur++;
a = curCharacter();
stack.pop();
System.out.printf("%-6d %-20s %6s \n",(++count),stack.toString(),strToken.substring(cur, strToken.length()));
}else{
ERROR();
}
}else if(X.equals("#")){
if(X.equals(a)){
flag = false;
}else{
ERROR();
}
}else if(productionType() == true){
if(VNTI().equals("synch")){
ERROR();
}else if(VNTI().equals("ε")){
stack.pop();
System.out.printf("%-6d %-20s %6s %-1s->%-12s\n",(++count),stack.toString(),strToken.substring(cur, strToken.length()),X,VNTI());
}else{
pushStack();
}
}else{
ERROR();
}
}
}
//出现错误
protected void ERROR(){
System.out.println("输入串出现错误,无法进行分析!!!");
System.exit(0);
}
//打印存储分析表
protected void printf(){
if(flag == false){
System.err.println("输入串正确!!!");
}else {
System.out.println("输入串错误!!!");
}
}
public static void main(String[] args) {
GramerAnasys gramerAnasys= new GramerAnasys();
gramerAnasys.print();
gramerAnasys.init();
gramerAnasys.totalControlProgram();
gramerAnasys.printf();
}
}