原创:一个简单的句法分析程序,界面还算漂亮
来源:互联网 发布:ubuntu查看串口设备 编辑:程序博客网 时间:2024/04/28 23:59
程序一般,但是界面绝对体现我对美术天生的感觉^_^,题外话:决心远离这个行业,太BT,没人情味,就是一堆机器在操纵另一堆机器,太冷酷,不适合我
以后可能还会写程序,但仅仅作为爱好了
核心部分JCODER.H
#include "stdafx.h"
char *reserved[] = { "if","then",
"while","do",
"+","-","*","/",":=",
"=",">=","<=","<>",">","<",
";","(",")","#",
"begin","end"
};//total 21 tokens
//note index128 for variable
//note index256 for numbers
class error
{
public:
int offset;
char *reason;
}err;
class File
{
public:
static char *ReadFromFile(char *FileName);
public:
static char *writeToFile(char *FileName,char *buf);
};
class Number
{
public:
static int allNum(char *str,int len);
};
class Token
{
private:
int index;
char content[8];
Token *next;
Token *past;
int offset;
public:
void CreateNextToken(int index,char *content,int offset);
Token *getNext();
Token *getPast();
char *getContent();
int getIndex();
void setOffset(int offset);
int getOffset();
};
class JCoder
{
//<程序>::=begin <语句串> end
//<语句串>::=<语句>{;<语句>}
//<语句>::=<赋值语句>
//<赋值语句>::=ID:= <表达式>
//<表达式>::=<项>{+<项>|-<项>}
//<项>::=<因子>{*<因子>|/<因子>}
//<因子>::=ID | NUM | (<表达式>)
private:
static int getWord(char *source,int *index);
static Token *program(Token *First);
static Token *Lines(Token *First);
static Token *Sentence(Token *First);
static Token *Expression(Token *First);
static Token *ShortExpressions(Token *First);
static Token *Atom(Token *First);
public:
static Token *CreateTokens(char *source);
static bool Parse(Token *First);
};
////////////////////////////////for class File/////////////////////////////////
char *File::ReadFromFile(char *FileName)
{
HANDLE hFile;
char *buf;
hFile=CreateFile(FileName,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(hFile==INVALID_HANDLE_VALUE)
return (char *)0;
else
{
unsigned long numDone;
buf=new char[(sizeof(char)*GetFileSize(hFile,0)+16)];
ZeroMemory(buf,sizeof(char)*GetFileSize(hFile,0)+16);
ReadFile(hFile,buf,GetFileSize(hFile,0),&numDone,0);
FlushFileBuffers(hFile);
CloseHandle(hFile);
return buf;
}
}
char *File::writeToFile(char *FileName,char *buf)
{
HANDLE hFile;
hFile=CreateFile(FileName,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
if(hFile==INVALID_HANDLE_VALUE)
return (char *)0;
else
{
unsigned long numDone;
WriteFile(hFile,buf,strlen(buf),&numDone,0);
FlushFileBuffers(hFile);
CloseHandle(hFile);
return buf;
}
}
////////////////////////////////for class Number///////////////////////////////
int Number::allNum(char *str,int len)
{
while(len!=0)
{
if(!(*(str+len-1)>='0' && *(str+len-1)<='9'))
{
return -1;
}
len--;
}
return 1;
}
////////////////////////////////for class JCoder///////////////////////////////
int JCoder::getWord(char *source,int *len)
{
char *buf,*Bptr;
int i;
Bptr=buf=new char[strlen(source)+2];
ZeroMemory(Bptr,strlen(source)+2);
while(*(source)!=0 && *(source)!=' ' && *(source)!='/n' && *(source)!='/r')
{
*(buf)=*(source);
for(i=0;i<=20;i++)
{
if(strcmp(Bptr,reserved[i])==0)
{
//for remove the bug,">=,<=,==,!=,&&,||"
if(!strcmp(reserved[i],">") && *(source+1)=='=')
{
delete []Bptr;
return 10;
}
else if(!strcmp(reserved[i],"<") && *(source+1)=='=')
{
delete []Bptr;
return 11;
}
else if(!strcmp(reserved[i],"<") && *(source+1)=='>')
{
delete []Bptr;
return 12;
}
else
{
delete []Bptr;
return i;
}
}
else
{
if(strstr(Bptr,reserved[i])!=NULL)
{
if((Number::allNum(Bptr,buf-Bptr)==1))
{
*(len)=strlen(Bptr)-strlen(reserved[i]);
delete []Bptr;
return 256;
}
else
{
if(!(*(Bptr)>='0' && *(Bptr)<='9'))
{
*(len)=strlen(Bptr)-strlen(reserved[i]);
delete []Bptr;
return 128;
}
else
{
delete []Bptr;
return -1;
}
}
}
}
}
buf+=1;
source+=1;
}
if(Number::allNum(Bptr,buf-Bptr)==1)return 256;
if((*(Bptr)>='a' && *(Bptr)<='z')||(*(Bptr)>='A' && (*(Bptr)<='Z')))
{
delete []Bptr;
return 128;
}
else
{
delete []Bptr;
return -1;
}
}
Token *JCoder::CreateTokens(char *source)
{
int flag,len;
char buffer[32];
Token *Theader=new Token();
Token *Tptr;
Tptr=Theader;
char *sptr=source;
while((*(source)==' ' || *(source)=='/r' || *(source)=='/n'||*(source)=='/t') && *(source)!=0 )
source++;
if(*(source)==0){delete Theader;return 0;};
while ((flag=getWord(source,&len))>=0)
{
if(flag<=20)
Tptr->CreateNextToken(flag,reserved[flag],source-sptr);
else
{
ZeroMemory(buffer,32);
strncpy(buffer,source,len);
Tptr->CreateNextToken(flag,buffer,source-sptr);
}
Tptr=Tptr->getNext();
if(flag==128 || flag==256)
source+=len;
else
source+=strlen(reserved[flag]);
while((*(source)==' ' || *(source)=='/r' || *(source)=='/n'||*(source)=='/t') && *(source)!=0 )
source++;
if(*(source)==0)break;
}
if(flag!=-1)//-1 for a nomally end
return Theader;
else
{
err.offset=source-sptr;
err.reason="Word Parse Error";
Tptr=Theader;
while(Theader!=NULL)
{
Tptr=Theader->getNext();
delete Theader;
Theader=Tptr;
}
return 0;
}
}
Token *JCoder::Atom(Token *First)
{
Token *ptr=First;
if(ptr->getIndex()==128 || ptr->getIndex()==256)
{
return ptr->getNext();
}
else
{
if(ptr->getIndex()==16)
{
if(ptr->getNext()==0)
{
err.reason="Expression Expected";
err.offset=ptr->getOffset();
return 0;
}
ptr=JCoder::Expression(ptr->getNext());
if(ptr==0)return 0;
else
{
if(ptr->getIndex()==17)
return ptr->getNext();
else
{
err.reason="/")/" Expected";
err.offset=ptr->getOffset();
return 0;
}
}
}
else
return 0;
}
}
Token *JCoder::ShortExpressions(Token *First)
{
Token *ptr;
ptr=JCoder::Atom(First);
Atom:
if(ptr==0)return 0;
if(ptr->getIndex()==15)
return ptr;
if(ptr->getIndex()==17)
return ptr;//(b+a)
else
{
if(ptr->getIndex()==6 || ptr->getIndex()==7)
{
if(ptr->getNext()==0)
{
err.reason="Expression Expected";
err.offset=ptr->getOffset();
return 0;
}
else
ptr=JCoder::Atom(ptr->getNext());
goto Atom;
}
else
{
if(ptr->getIndex()==4 || ptr->getIndex()==5)
return ptr;
else
{
err.reason="Operator expected";
err.offset=ptr->getOffset();
return 0;
}
}
}
}
Token *JCoder::Expression(Token *First)
{
Token *ptr;
ptr=JCoder::ShortExpressions(First);
ShortExpression:
if(ptr==0)
return 0;
if(ptr->getIndex()==15)return ptr;
if(ptr->getIndex()==17)return ptr;
else
{
if(ptr->getIndex()==4 || ptr->getIndex()==5)
if(ptr->getNext()==0)
{
err.reason="Expression Expected";
err.offset=ptr->getOffset();
return 0;
}
else
ptr=JCoder::ShortExpressions(ptr->getNext());
goto ShortExpression;
}
}
Token *JCoder::Sentence(Token *First)
{
Token *ptr;
if(First->getIndex()==128)
{
ptr=First->getNext();
if(ptr->getIndex()!=8)
{
err.offset=ptr->getOffset();
err.reason="/":=/" Required,Syntax Error";
return 0;
}
ptr=ptr->getNext();
if(ptr==0)
{
err.offset=ptr->getOffset();
err.reason="Right Value Required";
return 0;
}
ptr=JCoder::Expression(ptr);
return ptr;
}
else
{
err.offset=First->getOffset();
err.reason="Left Value Required";
return 0;
}
}
Token *JCoder::Lines(Token *First)
{
Token *ptr;
ptr=JCoder::Sentence(First);
if(ptr==0)return 0;
SentenceLoop:
if(ptr->getIndex()==15)
{
if(ptr->getNext()==0)
{
err.offset=ptr->getOffset();
err.reason="Begin Without End";
return 0;
}
else if(ptr->getNext()->getIndex()==20)return ptr->getNext();
ptr=JCoder::Sentence(ptr->getNext());
if(ptr==0)return 0;
goto SentenceLoop;
}
else
{
if(ptr->getIndex()==16 || ptr->getIndex()==17)
{
err.offset=ptr->getOffset();
err.reason="Syntax Error,( and ) should be matched";
return 0;
}
else
{
err.offset=ptr->getOffset();
err.reason="Sentence should be ended with /";/"";
return 0;
}
}
}
bool JCoder::Parse(Token *First)
{
Token *ptr;
if(First->getIndex()==19)
{
ptr=JCoder::Lines(First->getNext());
if(ptr==0)return false;
if(ptr->getIndex()==20 && ptr->getNext()==0)return true;
else
{
err.offset=ptr->getOffset();
err.reason="Begin Without End";
return false;
}
}
else
{
err.offset=0;
err.reason="Code With Out Begin";
return false;
}
}
////////////////////////////////for class Token////////////////////////////////
void Token::CreateNextToken(int index,char *content,int offset)
{
this->next=new Token();
this->next->setOffset(offset);
this->next->index=index;
strcpy(this->next->content,content);
this->next->next=0;
this->next->past=this;
}
void Token::setOffset(int offset)
{
this->offset=offset;
}
int Token::getOffset()
{
return this->offset;
}
Token *Token::getNext()
{
return this->next;
}
Token *Token::getPast()
{
return this->past;
}
char *Token::getContent()
{
return this->content;
}
int Token::getIndex()
{
return this->index;
}
//usage:
//Token *t;
//bool result;
//t=JCoder::CreateTokens(File::ReadFromFile("test1.pas"));
//result=JCoder::Parse(t->getNext());
界面:
// JCoder.cpp : Defines the entry point for the application.
//
//关键字:begin end if then while do
//运算符、界符::= + - * / < <= > >= = <> ; ( ) #
//标识符和整形常数:
//ID= letter (letter | digit )*
//NUM= digit digit *
//Letter= a|b|c…|z
//Digit=0|1|2…|9
#include "stdafx.h"
#include "JCoder.h"
#include "commctrl.h"
#include <commdlg.h>
#include "resource.h"
#include "stdlib.h"
HWND hListView;
HWND hCodeText;
HWND hErrorText;
Token *t;
char *fileBuf;
int openFlag;
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("JCODER") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
InitCommonControls();
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (hInstance,MAKEINTRESOURCE(IDI_MAINICON)) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (GRAY_BRUSH) ;
wndclass.lpszMenuName = 0;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, // window class name
TEXT ("JCODER"), // window caption
WS_MINIMIZE | WS_MINIMIZEBOX | WS_BORDER | WS_SYSMENU, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
800, // initial x size
400, // initial y size
NULL, // parent window handle
LoadMenu(hInstance,MAKEINTRESOURCE(IDM_MENU)), // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static LVCOLUMN lvc;
static OPENFILENAME ofn ;
static int menuCmd;
static char fileName[2560]={0};
static TCHAR szFilter[] =TEXT ("SudoPascal Files (*.pas)/0*.pas/0/0") ;
static TCHAR szFileName[MAX_PATH], szTitleName[MAX_PATH] ;
char error[256];
char textBuf[256];
char *fileBuffer;
LVITEM lvi;
Token *ptr;
NMHDR *lpNMHDR;
int i;
switch (message)
{
case WM_CREATE:
{
hListView=CreateWindowEx(WS_EX_CLIENTEDGE,"SysListView32",NULL,WS_CHILD | WS_VISIBLE | LVS_SHAREIMAGELISTS | LVS_REPORT,1,1,300,348,hwnd,NULL,GetModuleHandle(NULL),0);
hCodeText=CreateWindowEx(WS_EX_CLIENTEDGE,"edit",NULL,WS_CHILD | WS_VISIBLE | ES_LEFT | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL,303,1,490,300,hwnd,NULL,GetModuleHandle(NULL),0);
hErrorText=CreateWindowEx(WS_EX_CLIENTEDGE,"static",NULL,WS_CHILD | WS_VISIBLE | WS_BORDER,303,303,490,49,hwnd,NULL,GetModuleHandle(NULL),0);
SendMessage(hListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP | LVS_EX_SUBITEMIMAGES | LVS_EX_GRIDLINES);
SendMessage(hListView, LVM_SETTEXTCOLOR, 0, 0x00ffff00);
SendMessage(hListView, LVM_SETBKCOLOR, 0, 0x00aaaaaa);
SendMessage(hListView, LVM_SETTEXTBKCOLOR, 0, 0x00aaaaaa);
lvc.mask=LVCF_TEXT|LVCF_FMT|LVCF_WIDTH;
lvc.fmt=LVCFMT_CENTER;
lvc.cx=100;
lvc.pszText="词法成分";
ListView_InsertColumn(hListView,0,&lvc);
lvc.pszText="序号";
ListView_InsertColumn(hListView,1,&lvc);
lvc.pszText="位置";
ListView_InsertColumn(hListView,2,&lvc);
return 0 ;
}
case WM_DESTROY:
{
PostQuitMessage (0) ;
return 0 ;
}
case WM_NOTIFY:
{
lpNMHDR=(NMHDR *)lParam;
if(lpNMHDR->hwndFrom==hListView)
{
if(lpNMHDR->code==LVN_ITEMACTIVATE)
{
i=SendMessage(hListView,LVM_GETNEXTITEM,0,MAKELPARAM((UINT)LVNI_SELECTED,0));
if(i==-1)i=0;
lvi.mask=LVIF_TEXT;
lvi.iItem=i;
lvi.iSubItem=2;
lvi.pszText=textBuf;
lvi.cchTextMax=255;
SendMessage(hListView,LVM_GETITEM,0,(long)&lvi);
i=atoi(lvi.pszText);
lvi.iSubItem=0;
SendMessage(hListView,LVM_GETITEM,0,(long)&lvi);
SendMessage(hCodeText,EM_SETSEL,i,strlen(lvi.pszText)+i);
SetFocus(hCodeText);
}
}
}
case WM_COMMAND:
{
menuCmd=wParam;
menuCmd=menuCmd & 0x0000ffff;
if(menuCmd==IDM_OPEN)
{
ofn.lStructSize = sizeof (OPENFILENAME) ;
ofn.hwndOwner = hwnd ;
ofn.hInstance = NULL ;
ofn.lpstrFilter = szFilter ;
ofn.lpstrCustomFilter = NULL ;
ofn.nMaxCustFilter = 0 ;
ofn.nFilterIndex = 0 ;
ofn.nMaxFile = MAX_PATH ;
ofn.nMaxFileTitle = MAX_PATH ;
ofn.lpstrInitialDir = NULL ;
ofn.lpstrTitle = NULL ;
ofn.Flags = 0 ; // Set in Open and Close functions
ofn.nFileOffset = 0 ;
ofn.nFileExtension = 0 ;
ofn.lpstrDefExt = TEXT ("pas") ;
ofn.lCustData = 0L ;
ofn.lpfnHook = NULL ;
ofn.lpTemplateName = NULL ;
ofn.hwndOwner = hwnd ;
ofn.lpstrFile = szFileName;
ofn.lpstrFileTitle = szTitleName;
ofn.Flags = OFN_HIDEREADONLY | OFN_CREATEPROMPT ;
if(GetOpenFileName (&ofn))
{
if(fileBuf)
{
delete []fileBuf;
fileBuf=0;
}
openFlag=1;
SetWindowText(hErrorText,"File Selected,Let's make a try!");
SetWindowText(hCodeText,(fileBuf=File::ReadFromFile(ofn.lpstrFile)));
}
else
{
SetWindowText(hErrorText,"Please Specify a file");
openFlag=0;
}
return 0;
}
}
if(menuCmd==IDM_WORD)
{
if(t)
{
while(t->getNext())
{
t=t->getNext();
delete t->getPast();
}
delete t;
t=0;
}
if(openFlag==1)
{
fileBuffer=new char[64*1024];
ZeroMemory(fileBuffer,64*1024);
GetWindowText(hCodeText,fileBuffer,64*1024);
t=JCoder::CreateTokens(fileBuffer);
if(!t)
{
wsprintf(error,"error at %d,%s",err.offset,err.reason);
SetWindowText(hErrorText,error);
SendMessage(hCodeText,EM_SETSEL,err.offset,err.offset+1);
SetFocus(hCodeText);
}
else
{
ptr=t->getNext();
SendMessage(hListView,LVM_DELETEALLITEMS,0,0);
i=0;
while(ptr)
{
lvi.mask=LVIF_TEXT;
lvi.iItem=i;
lvi.iSubItem=0;
lvi.pszText=ptr->getContent();
SendMessage(hListView,LVM_INSERTITEM,0,(long)&lvi);
lvi.iSubItem=1;
wsprintf(textBuf,"%d",ptr->getIndex());
lvi.pszText=textBuf;
SendMessage(hListView,LVM_SETITEM,0,(long)&lvi);
lvi.iSubItem=2;
wsprintf(textBuf,"%d",ptr->getOffset());
lvi.pszText=textBuf;
SendMessage(hListView,LVM_SETITEM,0,(long)&lvi);
i++;
ptr=ptr->getNext();
}
SetWindowText(hErrorText,"Word Parse Ok");
}
delete []fileBuffer;
}
}
if(menuCmd==IDM_PARSE)
{
if(t)
{
if(!JCoder::Parse(t->getNext()))
{
SendMessage(hCodeText,EM_SETSEL,err.offset,err.offset+1);
SetFocus(hCodeText);
wsprintf(error,"error at %d,%s",err.offset,err.reason);
SetWindowText(hErrorText,error);
}
else
{
SetWindowText(hErrorText,"all is ok");
MessageBox(hwnd,"分析成功","提示",MB_OK);
}
}
}
if(menuCmd==IDM_SAVE)
{
fileBuffer=new char[64*1024];
ZeroMemory(fileBuffer,64*1024);
GetWindowText(hCodeText,fileBuffer,64*1024);
File::writeToFile(ofn.lpstrFile,fileBuffer);
delete []fileBuffer;
}
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
- 原创:一个简单的句法分析程序,界面还算漂亮
- 一个简单的RMI程序 [原创]
- 一个简单、漂亮、功能强大的Android日志程序:logger
- 一个简单、漂亮、功能强大的Android日志程序:logger
- 一个简单、漂亮、功能强大的Android日志程序:logger
- 一个简单、漂亮、功能强大的Android日志程序:logger
- 一个简单、漂亮、功能强大的Android日志程序:logger
- 一个简单、漂亮、功能强大的Android日志程序:logger
- 一个简单的登陆界面程序
- 写一个简单的Java界面程序
- VC++中创建漂亮的应用程序界面[原创]
- IOS制作一个漂亮的登录界面
- (原创)液晶的一个最简单的测试程序
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的(原创)
- 一个很漂亮的登录界面和注册界面
- [原创]一个漂亮的香水网页(还PSD下载)
- (Truly原创) 一个漂亮好用的模拟下拉框
- 一个还算简单的微信消息SDK(基于.Net Standard 2.0)
- 实用技巧Linux系统的经典使用技巧八则
- linux操作系统中如何临时增加swap空间
- 初学DTD
- Linux中文件查找技术大全
- 杭州地图
- 原创:一个简单的句法分析程序,界面还算漂亮
- ERP一般实施流程/步骤
- ERP专业词汇
- 哪个类可以或得文件所占空间的大小等属性
- 什么时候才彻底平静
- 由《函数式编程另类指南》联想到的哲学思想
- 关于C#与C/C++的个人看法
- 图书馆信息管理系统源代码
- Mingle: 做Agile, 用Mingle