無論是詞法分析,還是語法分析,給我的第一感覺就是邏輯要嚴謹。由于項目有自己一套完整的語言和語法,設計好其對應的詞法分析器和語法分析器顯得尤為重要。
這里給您提供一個免費的java詞法分析器下載
java詞法分析器實現原理步驟
先寫其正則式,然后NFA,然后DFA,然后對其進行優化,最后準備工作做好了,就可以開始寫代碼了。
下面對其里面的主要函數進行講解:
enum Token_Type {
keyword =1, //關鍵字
Identifier, //標識符
operatorr, //運算符
operatorrd, //單運算符
constant, //常量
escape, //轉義符
separator, //界限符
notype, //沒有類型
zhushi //注釋類型
};
對其單詞的類型定義成枚舉。
typedef struct Token {
Token_Type type; //其類型
char *lexeme ; //字符串
int value; //屬性值
}Token;
//返回單詞的結構。
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);//這個函數實現對關鍵字進行判斷
下面是源代碼:
/************************************************************************
* CopyRight@ice-snow studio *
* email:bingxuefenggu@126.com *
* qq: 405116890 *
************************************************************************/
//只考慮到整形常量
//實型沒考慮到
//需要解決轉義符如何描述的問題
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define TOKEN_LEN 100
enum Token_Type {
keyword =1, //關鍵字
Identifier, //標識符
operatorr, //運算符
operatorrd, //單運算符
constant, //常量
escape, //轉義符
separator, //界限符
notype, //沒有類型
zhushi //注釋類型
};
typedef struct Token {
Token_Type type; //其類型
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}
//以上是所有的關鍵字
};
FILE *fp1;// 要讀文件的描述符
int LineNo;//單詞所在的行數
static char TokenBuffer[TOKEN_LEN];//單詞符號的緩存區
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官方版
- 安卓官方手機版
- IOS官方手機版