無(wú)論是詞法分析,還是語(yǔ)法分析,給我的第一感覺(jué)就是邏輯要嚴(yán)謹(jǐn)。由于項(xiàng)目有自己一套完整的語(yǔ)言和語(yǔ)法,設(shè)計(jì)好其對(duì)應(yīng)的詞法分析器和語(yǔ)法分析器顯得尤為重要。
這里給您提供一個(gè)免費(fèi)的java詞法分析器下載
java詞法分析器實(shí)現(xiàn)原理步驟
先寫(xiě)其正則式,然后NFA,然后DFA,然后對(duì)其進(jìn)行優(yōu)化,最后準(zhǔn)備工作做好了,就可以開(kāi)始寫(xiě)代碼了。
下面對(duì)其里面的主要函數(shù)進(jìn)行講解:
enum Token_Type {
keyword =1, //關(guān)鍵字
Identifier, //標(biāo)識(shí)符
operatorr, //運(yùn)算符
operatorrd, //單運(yùn)算符
constant, //常量
escape, //轉(zhuǎn)義符
separator, //界限符
notype, //沒(méi)有類(lèi)型
zhushi //注釋類(lèi)型
};
對(duì)其單詞的類(lèi)型定義成枚舉。
typedef struct Token {
Token_Type type; //其類(lèi)型
char *lexeme ; //字符串
int value; //屬性值
}Token;
//返回單詞的結(jié)構(gòu)。
void InitScanner(char *ch){
fp1 = fopen(ch,"r+");
LineNo = 1;
}//初始化分析器。
void CloseScanner(){
fclose(fp1);
}//關(guān)閉分析器
void EmptyTokenString(){
memset(TokenBuffer,0,100);
}//清空緩沖區(qū)
static void AddCharTokenString(char Char)
{
int TokenLenth=strlen(TokenBuffer);
if(TokenLenth+1==sizeof(TokenBuffer)) return;
TokenBuffer[TokenLenth]=Char;
TokenBuffer[TokenLenth+1]='\0';
} //將一個(gè)字符添加到緩沖區(qū)
static char GetChar(){
char Char;
Char = fgetc(fp1);
return Char;
}//從文件中讀取一個(gè)字符
static void BackChar(char Char) {
if(Char!=EOF){
ungetc(Char,fp1);
}
}//將其字符后退一個(gè)。
static Token JudgeKeyToken(char *IDstring);//這個(gè)函數(shù)實(shí)現(xiàn)對(duì)關(guān)鍵字進(jìn)行判斷
下面是源代碼:
/************************************************************************
* CopyRight@ice-snow studio *
* email:bingxuefenggu@126.com *
* qq: 405116890 *
************************************************************************/
//只考慮到整形常量
//實(shí)型沒(méi)考慮到
//需要解決轉(zhuǎn)義符如何描述的問(wèn)題
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define TOKEN_LEN 100
enum Token_Type {
keyword =1, //關(guān)鍵字
Identifier, //標(biāo)識(shí)符
operatorr, //運(yùn)算符
operatorrd, //單運(yùn)算符
constant, //常量
escape, //轉(zhuǎn)義符
separator, //界限符
notype, //沒(méi)有類(lèi)型
zhushi //注釋類(lèi)型
};
typedef struct Token {
Token_Type type; //其類(lèi)型
char *lexeme ; //字符串
int value; //屬性值
}Token;
static Token Token_Tap[] = {
{keyword,"abstract",0x103},
{keyword,"boolean",0x103},
{keyword,"break", 0x103},
{keyword,"byte" ,0x103},
{keyword,"case",0x103},
{keyword,"catch",0x103},
{keyword,"char", 0x103},
{keyword, "class",0x103},
{keyword,"const" ,0x103},
{keyword,"continue" ,0x103},
{keyword,"default" , 0x103},
{keyword,"do",0x103},
{keyword,"double",0x103},
{keyword,"else",0x103},
{keyword,"extends",0x103},
{keyword,"false",0x103},
{keyword,"final",0x103},
{keyword,"finally",0x103},
{keyword,"float",0x103},
{keyword,"for",0x103},
{keyword,"goto",0x103},
{keyword,"if",0x103},
{keyword,"implements",0x103},
{keyword,"import",0x103},
{keyword,"instanceof",0x103},
{keyword,"int",0x103},
{keyword,"interface",0x103},
{keyword,"long",0x103},
{keyword,"native",0x103},
{keyword,"new",0x103},
{keyword,"null",0x103},
{keyword,"package",0x103},
{keyword,"private",0x103},
{keyword,"protected",0x103},
{keyword,"public",0x103},
{keyword,"return",0x103},
{keyword,"short",0x103},
{keyword,"static",0x103},
{keyword,"super",0x103},
{keyword,"switch",0x103},
{keyword,"synchronized",0x103},
{keyword,"this",0x103},
{keyword,"throw",0x103},
{keyword,"throws",0x103},
{keyword,"transient",0x103},
{keyword,"true",0x103},
{keyword,"try", 0x103},
{keyword,"void",0x103},
{keyword,"volatile",0x103},
{keyword,"while",0x103},
{constant,"true",0x105},
{constant,"false",0x105}
//以上是所有的關(guān)鍵字
};
FILE *fp1;// 要讀文件的描述符
int LineNo;//單詞所在的行數(shù)
static char TokenBuffer[TOKEN_LEN];//單詞符號(hào)的緩存區(qū)
void InitScanner(char *ch){
fp1 = fopen(ch,"r+");
LineNo = 1;
}
void CloseScanner(){
fclose(fp1);
}
void EmptyTokenString(){
memset(TokenBuffer,0,100);
}
static void AddCharTokenString(char Char)
{
int TokenLenth=strlen(TokenBuffer);
if(TokenLenth+1==sizeof(TokenBuffer)) return;
TokenBuffer[TokenLenth]=Char;
TokenBuffer[TokenLenth+1]='\0';
}
static char GetChar(){
char Char;
Char = fgetc(fp1);
return Char;
}
static void BackChar(char Char) {
if(Char!=EOF){
ungetc(Char,fp1);
}
}
static Token JudgeKeyToken(char *IDstring){
int loop;
Token token;
for(loop=0;loop<51;loop++){
if(strcmp(Token_Tap[loop].lexeme,IDstring)==0)
return Token_Tap[loop];
}
token.type = Identifier;
//strcpy(token.lexeme,IDstring);//youwenti.
token.lexeme = IDstring;
token.value = 0x104;
return token;
}
- PC官方版
- 安卓官方手機(jī)版
- IOS官方手機(jī)版