?? scandoc.cpp
字號:
// scanDoc.cpp : implementation of the CScanDoc class
//
#include "stdafx.h"
#include "scan.h"
#include "scanDoc.h"
//#include "sscan.h" //add by user
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//external var
extern CTraceBar g_TraceBar;
CEdit* g_pEditCtrl; //edit control
//extern SYMTAB_NODE_PTR symtab_root;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include <iostream.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define MAXRESERVED 8
const int namelen=40;
typedef struct symtab_node //二叉樹的結(jié)點結(jié)構(gòu)
{
struct symtab_node *left; //指向左孩子
struct symtab_node *right; //指向右孩子
char type[namelen+1];
char name[namelen+1]; //指向標識符的名字串
int lineno; //line number
}SYMTAB_NODE,*SYMTAB_NODE_PTR;
SYMTAB_NODE_PTR symtab_root=NULL;
typedef enum
{_ENDFILE,_ERROR,
IF,THEN,ELSE,END,REPEAT,UNTIL,READ,WRITE,
ID,NUM,
ASSIGN,EQ,LT,PLUS,MINUS,TIMES,OVER,LPAREN,RPAREN,SEMI
} tTokenType;
FILE* source; /* source code text file */
int lineno; /* source line number for listing */
int nStartChar=-1;
int nFilePos=-1;
#define MAXCHILDREN 3
#define MAXTOKENLEN 40
/* tokenString array stores the lexeme of each token */
char tokenString[MAXTOKENLEN+1];
/* states in scanner DFA */
typedef enum
{ START,INASSIGN,INCOMMENT,INNUM,INID,DONE }
StateType;
/* BUFLEN = length of the input buffer for
source code lines */
#define BUFLEN 256
static char lineBuf[BUFLEN]; /* holds the current line */
static int linepos = 0; /* current position in LineBuf */
static int bufsize = 0; /* current size of buffer string */
static int EOF_flag = FALSE; /* corrects ungetNextChar behavior on EOF */
/* lookup table of reserved words */
static struct
{ char* str;
tTokenType tok;
} reservedWords[MAXRESERVED]
= {{"if",IF},{"then",THEN},{"else",ELSE},{"end",END},
{"repeat",REPEAT},{"until",UNTIL},{"read",READ},
{"write",WRITE}};
//在由np指向的樹中查找標識符*name
SYMTAB_NODE_PTR search_symtab(char *name,SYMTAB_NODE_PTR np)
{
int cmp;
while(np!=NULL)
{
cmp=strcmp(name,np->name);
if(cmp==0) return(np);
np=cmp<0 ? np->left : np->right;
}
return(NULL);
}
void visit_symtab(const SYMTAB_NODE_PTR np)
{
if(np)
{
visit_symtab(np->left);
cout<<np->name<<endl;
visit_symtab(np->right);
}
}
//在由npp指向的樹中加入名為*name,值為value的標識符結(jié)點
SYMTAB_NODE_PTR enter_symtab(const char *name,const char *type , int line,SYMTAB_NODE_PTR &npp)
{
int cmp;
SYMTAB_NODE_PTR np1,np2;
SYMTAB_NODE_PTR new_nodep;
new_nodep=new symtab_node;
strncpy(new_nodep->name,name,namelen);
strncpy(new_nodep->type,type,namelen);
new_nodep->lineno=line;
new_nodep->left=new_nodep->right=NULL;
np1=npp;
while(np1 != NULL)
{
cmp=strcmp(name,np1->name);
np2=np1;
np1 =cmp <0 ? (np1->left) : (np1->right);
}
np1=new_nodep;
if(npp==NULL)
npp=new_nodep;
else cmp < 0 ? np2->left=np1 : np2->right=np1;
return(new_nodep);
}
/* getNextChar fetches the next non-blank character
from lineBuf, reading in a new line if lineBuf is
exhausted */
static int getNextChar(void)
{
nFilePos ++; //add for edit control ,start from 0;
if (!(linepos < bufsize))
{
lineno++;
if (fgets(lineBuf,BUFLEN-1,source))
{
// if (EchoSource) fprintf(listing,"%4d: %s",lineno,lineBuf);
bufsize = strlen(lineBuf);
linepos = 0;
return lineBuf[linepos++];
}
else
{ EOF_flag = TRUE;
return EOF;
}
}
else return lineBuf[linepos++];
}
/* ungetNextChar backtracks one character
in lineBuf */
static void ungetNextChar(void)
{
if (!EOF_flag) linepos-- ;
nFilePos--;
}
/* lookup an identifier to see if it is a reserved word */
/* uses linear search */
static tTokenType reservedLookup (char * s)
{ int i;
for (i=0;i<MAXRESERVED;i++)
if (!strcmp(s,reservedWords[i].str))
return reservedWords[i].tok;
return ID;
}
/****************************************/
/* the primary function of the scanner */
/****************************************/
/* function getToken returns the
* next token in source file
*/
tTokenType getToken(void)
{ /* index for storing into tokenString */
int tokenStringIndex = 0;
/* holds current token to be returned */
tTokenType currentToken;
/* current state - always begins at START */
StateType state = START;
/* flag to indicate save to tokenString */
int save;
while (state != DONE)
{
int c = getNextChar();
save = TRUE;
switch (state)
{ case START:
if (isdigit(c))
state = INNUM;
else if (isalpha(c))
state = INID;
else if (c == ':')
state = INASSIGN;
else if ((c == ' ') || (c == '\t') || (c == '\n'))
{
save = FALSE;
/* in edit component ,SetSel() takes '\n' as two chars,
* so nFilePos must plus 2
*/
if(c=='\n') nFilePos++;
}
else if (c == '{')
{ save = FALSE;
state = INCOMMENT;
}
else
{ state = DONE;
switch (c)
{ case EOF:
save = FALSE;
currentToken = _ENDFILE;
break;
case '=':
currentToken = EQ;
break;
case '<':
currentToken = LT;
break;
case '+':
currentToken = PLUS;
break;
case '-':
currentToken = MINUS;
break;
case '*':
currentToken = TIMES;
break;
case '/':
currentToken = OVER;
break;
case '(':
currentToken = LPAREN;
break;
case ')':
currentToken = RPAREN;
break;
case ';':
currentToken = SEMI;
break;
default:
currentToken = _ERROR;
break;
}
}
break;
case INCOMMENT:
save = FALSE;
if (c == EOF)
{ state = DONE;
currentToken = _ENDFILE;
}
/* in edit component ,SetSel() takes '\n' as two chars,
* so nFilePos must plus 2
*/
else if(c=='\n') nFilePos++;
else if (c == '}') state = START;
break;
case INASSIGN:
state = DONE;
if (c == '=')
currentToken = ASSIGN;
else
{ /* backup in the input */
ungetNextChar();
save = FALSE;
currentToken = _ERROR;
}
break;
case INNUM:
if (!isdigit(c))
{ /* backup in the input */
ungetNextChar();
save = FALSE;
state = DONE;
currentToken = NUM;
}
break;
case INID:
if (!isalpha(c))
{ /* backup in the input */
ungetNextChar();
save = FALSE;
state = DONE;
currentToken = ID;
}
break;
case DONE:
default: /* should never happen */
// fprintf(listing,"Scanner Bug: state= %d\n",state);
state = DONE;
currentToken = _ERROR;
break;
}
if ((save) && (tokenStringIndex <= MAXTOKENLEN))
tokenString[tokenStringIndex++] = (char) c;
if (state == DONE)
{ tokenString[tokenStringIndex] = '\0';
if (currentToken == ID)
currentToken = reservedLookup(tokenString);
}
}
/* if (TraceScan) {
fprintf(listing,"\t%d: ",lineno);
printToken(currentToken,tokenString);
}
*/ return currentToken;
} /* end getToken */
void maint()
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -