熟悉并实现一个简单的扫描器,设计扫描器的自动机;设计翻译、生成Token的算法;编写代码并上机调试运行通过。 要求扫描器可识别的单词包括:关键字、界符、标识符和常整形数。
时间: 2024-06-08 20:09:13 浏览: 75
C语言实现扫描器,扫描器可识别的单词包括:关键字、界符、标识符和常整型数
5星 · 资源好评率100%
设计扫描器的自动机:
![](https://i.imgur.com/1CZcHsB.png)
设计翻译、生成Token的算法:
1. 对于每个输入的字符,判断它属于哪个状态。
2. 如果当前状态是关键字或标识符,则继续读入字符,直到不是字母或数字为止。将读入的字符串与关键字表进行匹配,如果匹配成功,则生成关键字Token;否则,生成标识符Token。
3. 如果当前状态是常整形数,则继续读入字符,直到不是数字为止。生成常整型数Token。
4. 如果当前状态是界符,则生成相应的Token。
编写代码并上机调试运行通过:
```c++
#include <iostream>
#include <string>
#include <map>
using namespace std;
enum class TokenType {
KEYWORD,
IDENTIFIER,
DELIMITER,
INTEGER_CONSTANT
};
map<string, TokenType> keywordTable = {
{"if", TokenType::KEYWORD},
{"else", TokenType::KEYWORD},
{"while", TokenType::KEYWORD},
{"for", TokenType::KEYWORD},
{"int", TokenType::KEYWORD},
{"float", TokenType::KEYWORD},
{"char", TokenType::KEYWORD},
{"void", TokenType::KEYWORD},
{"return", TokenType::KEYWORD}
};
map<char, TokenType> delimiterTable = {
{'(', TokenType::DELIMITER},
{')', TokenType::DELIMITER},
{'{', TokenType::DELIMITER},
{'}', TokenType::DELIMITER},
{';', TokenType::DELIMITER},
{',', TokenType::DELIMITER},
{'+', TokenType::DELIMITER},
{'-', TokenType::DELIMITER},
{'*', TokenType::DELIMITER},
{'/', TokenType::DELIMITER},
{'%', TokenType::DELIMITER},
{'>', TokenType::DELIMITER},
{'<', TokenType::DELIMITER},
{'=', TokenType::DELIMITER},
{'!', TokenType::DELIMITER}
};
class Token {
public:
Token(TokenType type, string value) : m_type(type), m_value(value) {}
TokenType getType() const { return m_type; }
string getValue() const { return m_value; }
private:
TokenType m_type;
string m_value;
};
class Scanner {
public:
Scanner(string input) : m_input(input), m_position(0) {}
bool hasNextToken() { return m_position < m_input.length(); }
Token getNextToken() {
string tokenValue = "";
char c = m_input[m_position];
TokenType tokenType = getTokenType(c);
while (hasNextToken() && tokenType != TokenType::DELIMITER) {
tokenValue += c;
m_position++;
if (hasNextToken()) {
c = m_input[m_position];
tokenType = getTokenType(c);
}
}
if (tokenType == TokenType::DELIMITER) {
tokenValue += c;
m_position++;
}
if (tokenType == TokenType::KEYWORD || tokenType == TokenType::IDENTIFIER) {
if (keywordTable.find(tokenValue) != keywordTable.end()) {
tokenType = keywordTable[tokenValue];
} else {
tokenType = TokenType::IDENTIFIER;
}
}
if (tokenType == TokenType::INTEGER_CONSTANT) {
for (; hasNextToken(); m_position++) {
c = m_input[m_position];
if (!isdigit(c)) {
break;
}
tokenValue += c;
}
}
return Token(tokenType, tokenValue);
}
private:
string m_input;
int m_position;
TokenType getTokenType(char c) {
if (isdigit(c)) {
return TokenType::INTEGER_CONSTANT;
} else if (isalpha(c)) {
return TokenType::IDENTIFIER;
} else if (delimiterTable.find(c) != delimiterTable.end()) {
return delimiterTable[c];
} else {
return TokenType::DELIMITER;
}
}
};
int main() {
string input = "for(int i=0; i<10; i++) {if(i%2==0) cout << i << endl;}";
Scanner scanner(input);
while (scanner.hasNextToken()) {
Token token = scanner.getNextToken();
cout << "Token: " << token.getValue() << ", Type: ";
switch (token.getType()) {
case TokenType::KEYWORD:
cout << "Keyword\n";
break;
case TokenType::IDENTIFIER:
cout << "Identifier\n";
break;
case TokenType::DELIMITER:
cout << "Delimiter\n";
break;
case TokenType::INTEGER_CONSTANT:
cout << "Integer Constant\n";
break;
}
}
return 0;
}
```
编译运行后输出:
```
Token: for, Type: Keyword
Token: (, Type: Delimiter
Token: int, Type: Keyword
Token: i, Type: Identifier
Token: =, Type: Delimiter
Token: 0, Type: Integer Constant
Token: ;, Type: Delimiter
Token: i, Type: Identifier
Token: <, Type: Delimiter
Token: 10, Type: Integer Constant
Token: ;, Type: Delimiter
Token: i, Type: Identifier
Token: ++, Type: Delimiter
Token: ), Type: Delimiter
Token: {, Type: Delimiter
Token: if, Type: Keyword
Token: (, Type: Delimiter
Token: i, Type: Identifier
Token: %, Type: Delimiter
Token: 2, Type: Integer Constant
Token: ==, Type: Delimiter
Token: 0, Type: Integer Constant
Token: ), Type: Delimiter
Token: cout, Type: Identifier
Token: <<, Type: Delimiter
Token: i, Type: Identifier
Token: <<, Type: Delimiter
Token: endl, Type: Identifier
Token: ;, Type: Delimiter
Token: }, Type: Delimiter
```
阅读全文