java词法分析器 c语言_Java编写的C语言词法分析器

这是一个使用Java编写的C语言词法分析器,它能进行文件操作、帮助文档查看,支持词法分析功能,如关键字识别、运算符识别、分界符识别等。程序包括多个类,如JavaBean类、词法分析界面类和核心分析代码。核心代码中定义了关键字、运算符和分界符的数组,并提供了相应的判断方法。词法分析过程包括预处理、单词分割和类型检查,将输入的C语言代码转化为可识别的机器码。
摘要由CSDN通过智能技术生成

这是java编写的C语言词法分析器,我也是参考很多代码,然后核心代码整理起来,放在QQ空间和博客上,目的是互相学习借鉴,希望可以得到高手改进。这个词法分析器实现的功能有打开文件、保存文件、打开帮助文档、文本域内容的剪切和复制和黏贴、进行词法分析

程序的项目结构如图,Word类和Unidentifiable类是两个JavaBean类,存放的参数有两个row(整型)、word(String),row用于获取行数,word用于获取标识符,LexerFrame是词法分析器的界面类,Analyze封装了进行词法分析的核心代码 ,doc文件夹放一个帮助文档,当用户点击帮助按钮时可以弹出来以帮助用户使用。

//核心程序:

package com.lexer;

import java.util.ArrayList;

/**

*1~20号为关键字,用下标表示,i+1就是其机器码;21~40号为操作符,用下标表示,i+21就是其机器码;41~60号为分界符,

*  用下标表示,i+41就是其机器码;用户自定义的标识符,其机器码为51;常数的机器码为52;不可以识别的标识符,其机器码为0

*/

public class Analyze {

//关键字

private String keyword[]={"int","long","char","if","else","for","while","return","break","continue",

"switch","case","default","float","double","void","struct","static","do","short"};

//运算符

private String operator[]={"+","-","*","/","%","=",">","=","<=","++","--","&","&&","||","[","]"};

//分界符

private String delimiter[]={",",";","(",")","{","}","\'","\"",":","#"};

public Analyze() {

}

/**

* 判断是否是数字

*/

public boolean isDigit(char ch){

if(ch>='0'&&ch<='9'){

return true;

}else{

return false;

}

}

/**

* 判断是否是字母的函数

*/

public boolean isLetter(char ch){

if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){

return true;

}else{

return false;

}

}

/**

* 判断是否由两个运算符组成

*/

public boolean isTwoOperator(String str,char ch){

char lc;

int flag=0;

if(str.length()>1||str.length()==0){//字符数大于2和无字符的情况

return false;

}else{//字符数等于2的情况

lc=str.charAt(str.length()-1);

if(ch=='='&&(lc=='>'||lc=='

}else if(ch=='+'&&lc=='+'){

}else if(ch=='-'&&lc=='-'){

}else if(ch=='|'&&lc=='|'){

}else if(ch=='&'&&lc=='&'){

}else{

return false;//否就返回false

}

return true;//其它符号的情况都返回true

}

}

/**

* 获取关键字的机器码

*/

public int getKeywordOpcodes(String str){

int i;

for(i=0;i

if(str.equals(keyword[i]))

break;

}

if(i

return i+1;//返回关键字的机器码

}else{

return 0;

}

}

/**

* 获取操作符的机器码

*/

public int getOperatorOpcodes(String str){

int i;

for(i=0;i

if(str.equals(operator[i]))

break;

}

if(i

return i+21;//返回操作符的机器码

else

return 0;

}

/**

* 获取分界符的机器码

*/

public int getDelimiterOpcodes(String str){

int i;

for(i=0;i

if(str.equals(delimiter[i]))

break;

}

if(i

return i+41;//返回分界符的机器码

else

return 0;

}

/**

* 判断字符是否可以识别

*/

public boolean isIdent(String str){

char ch;

int i;

for(i=0;i

ch=str.charAt(i);

//非数字串的情况和非由英文字母组成的字符串

if((i==0&&!isLetter(ch))||(!isDigit(ch)&&!isLetter(ch))){

break;

}

}

if(i

return false;

}else{

return true;

}

}

/**

*

* 预处理函数

*/

public String preFunction(String str){

String ts="";

int i;

char ch,nc;

//这里的i

for(i=0;i

ch=str.charAt(i);

nc=str.charAt(i+1);

if(ch=='\n'){//如果字符是换行符,将\n换成$

ch='$';

ts=ts+ch;

}else if(ch==' '||ch=='\r'||ch=='\t'){

if(nc==' '||nc=='\r'||ch=='\t'){

continue;//连续' '或者'\t'或者'\r'的情况,直接跳过

}else{

ch=' ';//一个' '或者'\t'或者'\r'的情况,将这些字符换成' '

ts=ts+ch;

}

}else{

ts=ts+ch;//将字符连起来

}

}

ch=str.charAt(str.length()-1);

if(ch!=' '&&ch!='\r'&&ch!='\t'&&ch!='\n'){

ts=ts+ch;

}

return ts;

}

/**

* 将字符串分成一个个单词,存放在数组列表

*/

public ArrayList divide(String str){

ArrayList list=new ArrayList();

String s="";

char ch;

int i;

int row=1;

for(i=0;i

ch=str.charAt(i);

if(i==0&&ch==' ')//字符串的第一个字符

continue;

if(ch==' '){//' '或者'\t'或者'\r'的情况

if(s!=""){

list.add(new Word(row, s));

s="";//置空

}else{

continue;

}

}else if(isDigit(ch)||isLetter(ch)){

if(s==""||isDigit(s.charAt(s.length()-1))||isLetter(s.charAt(s.length()-1))){

s = s + ch;

}else{

list.add(new Word(row, s));

s = "";

s=s + ch;

}

}else{

if(isTwoOperator(s, ch)){//两个运算符的情况

s = s + ch;

}else{

if(s==""&&ch!='$'){

s = s + ch;

}else if(s==""&&ch=='$'){//若检测到$符号,就换行

row++;//行数加一

}else{

list.add(new Word(row, s));

s = "";

if(ch!='$'){

s=s + ch;

}else{

row++;

}

}

}

}

}

if(s!=""){

list.add(new Word(row, s));

}

return list;

}

/**

* 判断字符串是数字串,单个字符,还是一个字符串

*/

public int check(String str){

char ch;

ch=str.charAt(0);

if(ch>='0'&&ch<='9'){

return 1;//数字串

}

if(str.length()==1)

return 2;//单个字符

else

return 3;//一个字符串

}

/**

*

* 检查字符串是否为数字串,返回其机器码

*/

public int checkDigit(String str){

int i;

char ch;

for(i=0;i

ch=str.charAt(i);

if(ch>'9'||ch

break;

}

if(i

return 0;//不可识别的情况

}else{

return 52;//常数

}

}

/**

*

* 检查字符串是否为单个字符,返回其机器码

*/

public int checkChar(String str){

if(getOperatorOpcodes(str)!=0){//操作符

return getOperatorOpcodes(str);

}else if(getDelimiterOpcodes(str)!=0){//分界符

return getDelimiterOpcodes(str);

}else if(isIdent(str)){

return 51;//用户自定义标识符的机器码

}else{

return 0;//不可以被识别的标识符,机器码为0

}

}

/**

*

* 检查字符串是否为字符串,返回其机器码

*/

public int checkString(String str){

if(getOperatorOpcodes(str)!=0){//操作符

return getOperatorOpcodes(str);

}else if(getKeywordOpcodes(str)!=0){//关键字

return getKeywordOpcodes(str);

}else if(isIdent(str)){

return 51;//用户自定义标识符的机器码

}else{

return 0;//不可以被识别的标识符,机器码为0

}

}

}

//********************************************************************************************************************

在界面类写这个方法来调用方法

/**

* 词法分析

*/

public void doTokenizing(){

consoleTextArea.setText(null);

ArrayList wlist=new ArrayList();

ArrayList ulist=new ArrayList();

String s,ts,str;

Word word;

int i;

int opcodes=-1;

int errorNum=0;

int count=0;

s=fileContentTextArea.getText();

if(s.length()>1){

ts=analyze.preFunction(s);

wlist=analyze.divide(ts);

values=new String[wlist.size()][3];

while(wlist.size()>0){

word=(Word)wlist.remove(0);

str=word.getWord();

i=analyze.check(str);

switch (i) {

case 1:

opcodes=analyze.checkDigit(str);

break;

case 2:

opcodes=analyze.checkChar(str);

break;

case 3:

opcodes=analyze.checkString(str);

break;

}

if(opcodes==0){

Unidentifiable u=new Unidentifiable(word.getRow(), str);

ulist.add(u);

errorNum++;

}

values[count][0]=String.valueOf(word.getRow());

values[count][1]=str;

values[count][2]=String.valueOf(opcodes);

count++;

}

//更新表格内容

DefaultTableModel model=(DefaultTableModel)table.getModel();

while(model.getRowCount()>0){

model.removeRow(model.getRowCount()-1);

}

model.setDataVector(values,title);

table=new JTable(model);

consoleTextArea.append("共有"+errorNum+"处错误!"+"\n");

while (ulist.size()>0) {

int r;

String string;

Unidentifiable uni=ulist.remove(0);

r=uni.getRow();

string=uni.getWord();

consoleTextArea.append("第"+r+"行:"+"错误,"+string+"\n");

}

}else{

int j;

j=JOptionPane.showConfirmDialog(this, "请输入程序!");

if(j!=JOptionPane.YES_OPTION){

return;

}

}

}

f96fda1c057095972c672940aeaee90f.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值