对于上次方块占位的时候,有空心方块 解决的方案是:以前是合起来,再分开避免的问题 现在直接用 showbrick 直接不画空心方块 就不做什么就可以了 这样直接ShowBackground ShowBrick 就可以了
对于词法分析器我们先从 单词数量开始.
这是一道平时很常见的习题或者面试题
Hello World. I love you.对以上文本(以空格作为单词分隔),统计单词个数 下面比较简单的版本:
#include"stdafx.h" #include<stdio.h> #include<string.h> int WordNum(char *str) { int nCount = 0; while (*str != 0) { if (*str == ' ') { nCount++; } str++; } return ++nCount; } int main(void) { char nArry[] = "Hello World. I love you. "; printf("%d\r\n",WordNum(nArry) ); return 0; }这个版本是有bug的 :比如中间加空格,后面加空格都会影响结果。 所以就知道,不能仅仅以空格为评判标准 就像我们怎么知道这是一个单词,以人的直观角度去判断 那就是遇到空格前面是什么状态 如果是非空格 那么计数加一,如果是空格那么不计数 讲一下算法:
分为两种状态,分为空格,非空格状态;由非空格到空格那么计数加一其他情况不计数 用图解释:然后根据图去写程序: 多余结束的时候我就图示舍去了 判断结束是否要加上1 就是判断‘\0’前面是否为非空格如果是那么计数加一
#include"stdafx.h" #include<stdio.h> #include<string.h> #define STATE_START 0 #define STATE_BLANK 1 #define STATE_NONSPACE 2 int WordNum(char *pszContent) { int nState = STATE_START; int nCount = 0; while (*pszContent != '\0') { if (nState == STATE_START) { if (*pszContent == ' ') { nState = STATE_BLANK; } else { nState = STATE_NONSPACE; } } else if (nState == STATE_BLANK) { if (*pszContent != ' ') { nState = STATE_NONSPACE; } } else if (nState == STATE_NONSPACE) { if (*pszContent == ' ') { nState = STATE_BLANK; nCount++; } } pszContent++; } if (nState==STATE_NONSPACE) { if (*pszContent == '\0') { nCount++; } } return nCount; } int main(void) { char nArry[] = "Hello World. I love you. "; printf("%d\r\n",WordNum(nArry) ); return 0; }以上就是状态机(又称自动机,有限状态的自动机) 常常用于词法分析过程制作词法分析器
词法分析就是将单词分类。比如C语言的字符,由多种分类:
标识符:以字母下划线开头,后面接字母,下划线,数字。数字:以数字开头,后面接任意数字分隔符号:\n \r \t ’ ’ 等当然有人会说0x1234 分隔符号还有其他等问题 ,今天讲的初级版本就不涉及了。 我们可以将以上版本同时用状态机器表达出来
对应程序如下 如果不用彩色的化 将printf解锁,将wirtchar注释掉就可以了
#include"stdafx.h" #include<stdio.h> #include<string.h> #include"setdisplay.h" #define STATE_START 0 #define STATE_ID 1 #define STATE_NUM 2 #define STATE_DELM 3 #define STATE_EOF 4 int g_nCount = 0; char* g_szWord = "int nValue1 = 1234;\nint nValue2 =5678;\n"; int IsDeline(char* pszContent) { if (*pszContent == '_') { return 1; } else { return 0; } } int IsNum(char* pszContent) { if ((*pszContent >= '1'&&*pszContent <= '9')) { return 1; } else { return 0; } } int IsID(char* pszContent) { if ((*pszContent >= 'a'&&*pszContent <= 'z') || (*pszContent >= 'A'&&*pszContent <= 'Z')) { return 1; } else { return 0; } } int IsDelimter(char* pszContent) { if (*pszContent == ' ' || *pszContent == '\n' || *pszContent == '\r' || *pszContent == '\t' || *pszContent == ';') { return 1; } else { return 0; } } void ShowIt(char* pszContent1, char* pszContent2) { for (size_t i = 0; i < pszContent2 - pszContent1; i++) { printf("%c", *(pszContent1 + i)); } printf("\r\n"); pszContent1 = pszContent2; } void Lexer(char *pszContent) { char* pStartContent = NULL;//开始指针 int nState = STATE_START; while (*pszContent != '\0') { char* pszNextContent = pszContent; if (nState == STATE_START) { if (IsID(pszNextContent) || IsDeline(pszNextContent)) { pStartContent = pszContent;//记录开始标识 nState = STATE_ID; } else if (IsNum(pszNextContent)) { pStartContent = pszContent; nState = STATE_NUM; } else if (IsDelimter(pszNextContent)) { nState = STATE_DELM; } } else if (nState == STATE_ID) { if (IsDelimter(pszNextContent)) { WriteChar(g_nCount, 0, "找到一个变量", SetConsoleColor(COLOR_LIGHTBLUE, COLOR_BLACK)); g_nCount++; /* printf("找到一个变量");*/ ShowIt(pStartContent, pszContent); nState = STATE_DELM; } else { } } else if (nState == STATE_NUM) { if (IsDelimter(pszNextContent)) { WriteChar(g_nCount, 0, "找到一个数字", SetConsoleColor(COLOR_THIN_LIGHT_GREEN, COLOR_BLACK)); /*printf("找到一个数字");*/ g_nCount++;//坐标加1 ShowIt(pStartContent, pszContent); nState = STATE_DELM; } else { } } else if (nState == STATE_DELM) { if (IsID(pszNextContent)) { pStartContent = pszContent; nState = STATE_ID; } else if (IsNum(pszNextContent) || IsDeline(pszNextContent)) { pStartContent = pszContent; nState = STATE_NUM; } } pszContent++; } } int main(void) { Lexer(g_szWord); return 0; }