⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sescan.c

📁 功能丰富的串口通讯程序
💻 C
字号:
/*---------------------------------------------------------------------------+| Free form input scanner+---------------------------------------------------------------------------*/#include <stdio.h>#include <assert.h>#include <stdlib.h>#include <ctype.h>#include <string.h>#include "SeParse.h"#include "y.tab.h"/*---------------------------------------------------------------------------+| parse buffer - stores the string to be parsed (logical line)+---------------------------------------------------------------------------*/static unsigned parseBufLen;static unsigned parseBufNextCh;static char* 	parseBuf;void scSetInputBuffer(line)	 char *line ;{  assert(line != 0);  parseBufNextCh 	= 0;  parseBufLen      	= strlen(line);  parseBuf		= line;}int scGetChar() {  if (parseBufNextCh < parseBufLen) {#ifdef TEST    printf("Reading char %c\n", parseBuf[parseBufNextCh]);#endif    return parseBuf[parseBufNextCh++];  }  else    return EOF;}void scUngetChar(c)	 int c;{  if (parseBufNextCh > 0)    parseBuf[--parseBufNextCh] = c;}int scLook() {  if (parseBuf != 0)    return parseBuf[parseBufNextCh];  else    return EOF;}/*---------------------------------------------------------------------------+| strBuf - stores word to be returned+---------------------------------------------------------------------------*/#define GROW_SIZE 100static char *strBuf = 0;static unsigned strBufSize = 0;static unsigned strBufNextCh = 0;static void _growBuf(size)	 unsigned size;{  if (strBuf == 0)    strBuf = (char *)malloc(strBufSize = size + GROW_SIZE);  else if (strBufSize < (strBufNextCh + size + 1)) {    strBufSize += (size + 1) + GROW_SIZE;    strBuf = (char *)realloc(strBuf, strBufSize);  }}static void _startWord() {  strBufNextCh = 0;}static void _addCh(ch)	 int ch;{  _growBuf(1);  strBuf[strBufNextCh++] = ch;}static char* _getWd() {  if (strBuf != 0) strBuf[strBufNextCh] = 0;  strBufNextCh = 0;  return strBuf;}/*---------------------------------------------------------------------------+| scanner state+---------------------------------------------------------------------------*/enum SC_STATE {  SC_IN_WORD,  SC_IN_STR,  SC_OUTSIDE,};static ScanState = SC_OUTSIDE;static ScanDelim = 0;	/* Current string delimiter */void NEW_STATE(st)	 int st;{#ifdef TEST  static char* state_names[] = { "InWord", "InStr", "Out", "NONE" };  printf("**Entering state %s\n", state_names[st]);#endif  ScanState = st;}#define C_ESC BACK_CHAR#define C_SPACE ' '#define C_SEP ';'#define C_STR '"'int cType(c)	 int c;{  if (isspace(c)) return C_SPACE;  switch (c) {  case CTRL_CHAR: case BACK_CHAR: return C_ESC;  case ';' : case ',' : case '(' : case ')' : return C_SEP;  case '"' : case '\'' : return C_STR;  default : return c;  }}int doEsc();/*---------------------------------------------------------------------------+| scNextWord breaks lines into sequences of words|| Args: recognize_seps - 1 == recognize and return "();,"|			 0 == ignore those and put them into words|	wd - pointer to last recognized word, = 0 if at end of line|| Returns: input token type (usually a representative char)+---------------------------------------------------------------------------*/int scNextWord(recognize_seps, wd)	 int recognize_seps; 	 char **wd;{  int c;  while ((c = scGetChar()) != EOF) {    switch (ScanState) {    case SC_OUTSIDE:      switch (cType(c)) {      case C_ESC: NEW_STATE(SC_IN_WORD); _startWord(); _addCh(doEsc(c)); break;      case C_SPACE: 							break;      case C_SEP: if (recognize_seps) return c; 		  else {		    NEW_STATE(SC_IN_WORD); _startWord(); _addCh(c);		  }							break;      case C_STR: NEW_STATE(SC_IN_STR);  _startWord(); ScanDelim = c; 	break;      default:    NEW_STATE(SC_IN_WORD); _startWord(); _addCh(c);	break;      }      break;    case SC_IN_STR:      switch (cType(c)) {      case C_STR: 	if (ScanDelim == c) { NEW_STATE(SC_OUTSIDE); *wd = _getWd(); 			      return WORD;			    }	else  _addCh(c);						break;      case C_ESC: _addCh(doEsc(c)); 					break;      default:	  _addCh(c); 						break;      }      break;    case SC_IN_WORD:      switch (cType(c)) {      case C_ESC: _addCh(doEsc(c)); 					break;      case C_STR: NEW_STATE(SC_IN_STR); ScanDelim = c; 			break;      case C_SEP: 	if (recognize_seps) {	  ScanState = SC_OUTSIDE; *wd = _getWd(); scUngetChar(c); 	  return WORD;	}	else	  _addCh(c);						break;      case C_SPACE: NEW_STATE(SC_OUTSIDE); *wd = _getWd(); return WORD;break;      default: _addCh(c);						break;      }      break;    default: perror("Unknown state"); abort();      break;    }  }  switch(ScanState) {  case SC_IN_WORD: *wd = _getWd(); NEW_STATE(SC_OUTSIDE); return WORD;   case SC_IN_STR:  *wd = _getWd(); NEW_STATE(SC_OUTSIDE); return WORD;   case SC_OUTSIDE: return 0;  default:  perror("Unknown state"); abort();  }}/*---------------------------------------------------------------------------+| getOct - read an octal number with up to 3 digits+---------------------------------------------------------------------------*/int getOct(){  char intstr[4]; int next = 0;  int ch;  while ((ch = scGetChar()) != EOF && next <= 3)     if (isdigit(ch))      intstr[next++] = ch;    else if (ch != EOF) {       scUngetChar(ch);       break;    }    intstr[next]=0;  return strtol(intstr, NULL,  8);}    /*---------------------------------------------------------------------------+| Mapping table for the \[a-z] sequences: we let the C compiler initialize| them for us... Of course we can change the value of a particular char if| we feel like it.+---------------------------------------------------------------------------*/static char special[26] = { '\a', '\b', 'c', 'd', 'e', '\f', 'g', 'h', 'i', 'j', 'k', 'l',   'm', '\n', 'o', 'p', 'q', '\r', 's', '\t', 'u', '\v', 'w', 'x',  'y', 'z'};/*---------------------------------------------------------------------------+| doEsc - process esc (\) and control (^) sequences+---------------------------------------------------------------------------*/int doEsc(escChar)	 int escChar;{  int     c = scGetChar();  switch (escChar) {  case BACK_CHAR:    	 if (c == EOF) return escChar;    else if (isdigit(c)) { scUngetChar(c); return getOct(); }    else if (islower(c)) return special[c - 'a'];    else return c;    break;  case CTRL_CHAR:     if	    (islower(c)) return c - 'a' + 1;    else if (isupper(c)) return c - 'A' + 1;    else   { scUngetChar(c);  return escChar;  }    break;  default:    perror("Unknown escape sequence"); abort();  }}/*---------------------------------------------------------------------------+| yylex - interface with yacc parser generator+---------------------------------------------------------------------------*/int yylex() {  int state = scNextWord(1, &yylval.sval);  return state;}/*---------------------------------------------------------------------------+| GetWord - return successive words in input line, 0 when finished+---------------------------------------------------------------------------*/char*GetNextWord() {  char *word;  if (scNextWord(0, &word) == 0) return "";  return word;}char*GetFirstWord(line) 	 char *line;{  scSetInputBuffer(line);  return GetNextWord();}#ifdef TESTmain(){  scSetInputBuf("Just to see if we'\\'re \\n\\033 able to distinguish' words and strings\"Also 'quotes' inside strings\" and 'strs \"inside quotes\"'Not to forget ^S and ^q control ^ chars");  while (lGetWord() != 0);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -