package SyntaxAnalyze;
import java.util.ArrayList;
import java.util.List;
public class Analyse {
String expression;
int i;
boolean isNum;
int begin;
List<Token> tokens=new ArrayList<Token>();
List<String> errors=new ArrayList<String>();
int row_index=0;
int error_index=0;
int parsign=0;
//对表达式进行处理
public void analyseExpression(String str){
expression=str;
i=0;
isNum=false;
begin=0;
row_index++;
while(i<=expression.length()-1){
String ch=expression.substring(i,i+1);
if(analyseIsNum(ch)){
isNum=true;
if(isNum){
begin=i;
}
passNum();
i++;
if(i<=expression.length()-1 && expression.substring(i,i+1).equals(".")){
analyseAfterDot(begin);
}
else{
Token token=new Token("5", expression.substring(begin,i),expression.substring(begin,i), "int");
tokens.add(token);
isNum=false;
}
}
else if(ch.equals("0")){
if(i<=expression.length()-1){
if(analyseIsNum(expression.substring(i+1,i+2)) || expression.substring(i+1,i+2).equals("0")){
errors.add("Error"+(++error_index)+":"+"第"+row_index+"行"+"0的位置有误");
i++;
isNum=false;
}
else{
analyseAfterZero();
}
}
else{
//如果已经遍历到最后一个字符而且字符为0,则字符0记为数字0
Token token=new Token("0",expression.substring(i,i+1),expression.substring(i,i+1),"int");
tokens.add(token);
i++;
isNum=false;
}
}
else{
analyseNotNum(ch);
}
}
for(int i=0;i<getTokens().size();i++){
if(getTokens().get(i).getStr().equals("(")){
parsign++;
}
else if(getTokens().get(i).getStr().equals(")")){
parsign--;
}
}
if(parsign>0){
errors.add("Error"+(++error_index)+":"+"第"+row_index+"行"+"左括号不匹配");
}
else if(parsign<0){
errors.add("Error"+(++error_index)+":"+"第"+row_index+"行"+"右括号不匹配");
}
}
//对字符0后面的字符进行处理,如果字符0后面的字符不是.则字符0记为数字0,否则进行小数点处理
public void analyseAfterZero(){
if(!expression.substring(i+1,i+2).equals(".")){
Token token=new Token("5",expression.substring(i,i+1),expression.substring(i,i+1),"int");
tokens.add(token);
i++;
}
else{
i++;
analyseAfterDot(i-1);
}
}
//分析小数点后的字符
public void analyseAfterDot(int begin){
//当小数点后面不是数字时,则将小数点前面数字存入,并判定小数点有误
if(i==expression.length()-1){
Token token=new Token("5",expression.substring(begin,i),expression.substring(begin,i),"int");
tokens.add(token);
errors.add("Error"+(++error_index)+":"+"第"+row_index+"行"+"“.”后面应该是数字");
i++;
isNum=false;
}
else if(!(analyseIsNum(expression.substring(i+1,i+2)) || expression.substring(i+1,i+2).equals("0"))){
Token token=new Token("5",expression.substring(begin,i),expression.substring(begin,i),"int");
tokens.add(token);
errors.add("Error"+(++error_index)+":"+"第"+row_index+"行"+"“.”后面应该是数字");
i++;
isNum=false;
}
else{
passNum();
Token token=new Token("8",expression.substring(begin,i+1),expression.substring(begin,i+1),"double");
tokens.add(token);
i++;
isNum=false;
}
}
//分析非数字字符
public void analyseNotNum(String ch){
isNum=false;
if(analyseIsOperator(ch)){
if(ch.equals("+")){
Token token=new Token("1",ch,"null","null");
tokens.add(token);
i++;
}
else if(ch.equals("-")){
Token token=new Token("2",ch,"null","null");
tokens.add(token);
i++;
}
else if(ch.equals("*")){
if(i<expression.length()-1 && (expression.substring(i+1,i+2).equals("*") || expression.substring(i+1,i+2).equals("/"))){
errors.add("Error"+(++error_index)+":"+"第"+row_index+"行"+ch+expression.substring(i+1,i+2)+"非法运算;");
i=i+2;
}
else{
Token token=new Token("3",ch,"null","null");
tokens.add(token);
i++;
}
}
else if(ch.equals("/")){
if(i<expression.length()-1 && (expression.substring(i+1,i+2).equals("*") || expression.substring(i+1,i+2).equals("/"))){
errors.add("Error"+(++error_index)+":"+"第"+row_index+"行"+ch+expression.substring(i+1,i+2)+"非法运算;");
i=i+2;
}
else{
Token token=new Token("4",ch,"null","null");
tokens.add(token);
i++;
}
}
}
else if(ch.equals("(")){
if(i!=0 && analyseIsNum(expression.substring(i-1,i))){
errors.add("Error"+(++error_index)+":"+"第"+row_index+"行"+"”"+expression.substring(i-1,i)+"“后面不能直接跟"+"“(”;");
i++;
}
else{
Token token=new Token("6",ch,"null","null");
tokens.add(token);
i++;
}
}
else if(ch.equals(")")){
if(analyseIsOperator(expression.substring(i-1,i))){
errors.add("Error"+(++error_index)+":"+"第"+row_index+"行"+"“"+expression.substring(i-1,i)+"”后面不能直接跟"+"“)”;");
i++;
}
else{
Token token=new Token("7",ch,"null","null");
tokens.add(token);
i++;
}
if(i!=expression.length()&&analyseIsNum(expression.substring(i,i+1))){
errors.add("Error"+(++error_index)+":"+"第"+row_index+"行"+"“)”后面不能直接跟数字;");
i++;
}
}
else{
if(i==0 && expression.substring(i,i+1).equals(".")){
errors.add("Error"+(++error_index)+":"+"第"+row_index+"行"+"“.”前面应该是数字");
i++;
}
else if(i==0){
errors.add("Error"+(++error_index)+":"+"第"+row_index+"行"+"存在非法字符“"+expression.substring(i,i+1)+"”;");
i++;
}
else if(i==expression.length()-1 && expression.substring(i,i+1).equals(".")){
errors.add("Error"+(++error_index)+":"+"第"+row_index+"行"+"“.”后面应该是数字");
i++;
}
else{
if(expression.substring(i,i+1).equals(".")){
errors.add("Error"+(++error_index)+":"+"第"+row_index+"行"+"“"+expression.substring(i-1,i)+"”后面不能跟“"+expression.substring(i,i+1)+"”;");
i++;
}
else{
errors.add("Error"+(++error_index)+":"+"第"+row_index+"行"+"“"+expression.substring(i-1,i)+"”后面存在非法字符“"+expression.substring(i,i+1)+"”;");
i++;
}
}
}
}
//判断字符是否为数字
public boolean analyseIsNum(String ch){
if(ch.equals("1")||ch.equals("2")||ch.equals("3")||ch.equals("4")||ch.equals("5")||ch.equals("6")||ch.equals("7")||ch.equals("8")||ch.equals("9")){
return true;
}
else{
return false;
}
}
//判断字符是否为操作符
public boolean analyseIsOperator(String ch){
if(ch.equals("+")||ch.equals("-")||ch.equals("*")||ch.equals("/")){
return true;
}
else{
return false;
}
}
//若是数字,直接跳过,检测下一个字符
public void passNum(){
while(i+1<expression.length()){
if(analyseIsNum(expression.substring(i+1,i+2))||expression.substring(i+1,i+2).equals("0")){
i++;
}
else{
break;
}
}
}
//获取单词集
public List<Token> getTokens(){
return tokens;
}
//获取错误提示集
public List<String> getErrors(){
return errors;
}
}