这个ToKen类和TokenType类怎么写
时间: 2024-03-29 22:11:29 浏览: 27
ToKen类和TokenType类通常用于词法分析器(Lexical Analyzer),用于将输入的源代码分解成词法单元(Token)并进行分类。以下是一个简单的示例:
```python
class Token:
def __init__(self, type, value):
self.type = type
self.value = value
class TokenType:
# Keywords
IF = 'IF'
ELSE = 'ELSE'
WHILE = 'WHILE'
# Operators
PLUS = 'PLUS'
MINUS = 'MINUS'
TIMES = 'TIMES'
DIVIDE = 'DIVIDE'
# Punctuation
LPAREN = 'LPAREN'
RPAREN = 'RPAREN'
SEMICOLON = 'SEMICOLON'
```
在这个示例中,Token类包含一个type属性和一个value属性,分别表示Token的类型和值。TokenType类则定义了不同类型的Token,包括关键字(Keywords)、操作符(Operators)和标点符号(Punctuation)等。这些类型可以在词法分析器中用于分类Token,从而进行后续的语法分析和执行。
相关问题
优化以下方法: private Token nextToken() { Token result; if (!hasEnd) { if (index < source.length()) { switch (source.charAt(index)) { case '.': result = new Token(TokenType.DOT, source.charAt(index)); // System.out.println("DOT"); break; case '\': result = new Token(TokenType.LAMBDA, source.charAt(index)); // System.out.println("LAMBDA"); break; case '(': result = new Token(TokenType.LPAREN, source.charAt(index)); // System.out.println("LPAREN"); break; case ')': result = new Token(TokenType.RPAREN, source.charAt(index)); // System.out.println("RPAREN"); break; case ' ': result = new Token(TokenType.BLANK, source.charAt(index)); break; default: if ('a' <= source.charAt(index) && source.charAt(index) <= 'z') { int temp = index + 1; while (temp < source.length() && (('a' <= source.charAt(temp) && source.charAt(temp) <= 'z') || ('A' <= source.charAt(temp) && source.charAt(temp) <= 'Z'|| ('0' <= source.charAt(temp) && source.charAt(temp) <= '9')))) temp++; result = new Token(TokenType.LCID, source.substring(index, temp)); // System.out.println("LCID"); } else { result = new Token(TokenType.EOF, ""); // System.out.println("EOF"); } } } else { result = new Token(TokenType.EOF, ""); System.out.println("EOF"); hasEnd = true; } } else result = new Token(TokenType.EOF, ""); return result; }
可以考虑以下优化:
1. 减少重复代码
可以将 `result = new Token(TokenType.xxx, source.charAt(index));` 的代码抽取出来,减少重复的代码。
2. 减少字符串拼接
在处理 `LCID` 类型的 token 时,使用了 `source.substring(index, temp)` 将子串拼接成新的字符串。这个操作比较耗时,可以考虑将 `LCID` 类型 token 的值存储为起始和结束索引,而不是字符串。
3. 使用 Map 存储字符类型
将每个字符对应的 token 类型存储到一个 Map 中,这样可以避免使用多个 if/else 语句判断每个字符的类型。
综上所述,可以将代码修改为以下形式:
```
private static final Map<Character, TokenType> TOKEN_MAP = new HashMap<>();
static {
TOKEN_MAP.put('.', TokenType.DOT);
TOKEN_MAP.put('\\', TokenType.LAMBDA);
TOKEN_MAP.put('(', TokenType.LPAREN);
TOKEN_MAP.put(')', TokenType.RPAREN);
TOKEN_MAP.put(' ', TokenType.BLANK);
}
private Token nextToken() {
Token result;
if (!hasEnd) {
if (index < source.length()) {
char ch = source.charAt(index);
TokenType type = TOKEN_MAP.get(ch);
if (type != null) {
result = new Token(type, ch);
} else if ('a' <= ch && ch <= 'z') {
int end = index + 1;
while (end < source.length()) {
char nextCh = source.charAt(end);
if (!('a' <= nextCh && nextCh <= 'z') &&
!('A' <= nextCh && nextCh <= 'Z') &&
!('0' <= nextCh && nextCh <= '9')) {
break;
}
end++;
}
result = new Token(TokenType.LCID, index, end - 1);
} else {
result = new Token(TokenType.EOF, "");
}
} else {
result = new Token(TokenType.EOF, "");
System.out.println("EOF");
hasEnd = true;
}
} else {
result = new Token(TokenType.EOF, "");
}
return result;
}
```
其中 `Token` 类的定义可以修改为:
```
class Token {
enum TokenType {
DOT, LAMBDA, LPAREN, RPAREN, BLANK, LCID, EOF
}
final TokenType type;
final char value;
final int start; // LCID 类型 token 的起始索引
final int end; // LCID 类型 token 的结束索引
Token(TokenType type, char value) {
this(type, value, -1, -1);
}
Token(TokenType type, int start, int end) {
this(type, '\0', start, end);
}
Token(TokenType type, char value, int start, int end) {
this.type = type;
this.value = value;
this.start = start;
this.end = end;
}
}
```
不改变类的定义,优化以下方法: private Token nextToken() { Token result; if (!hasEnd) { if (index < source.length()) { switch (source.charAt(index)) { case '.': result = new Token(TokenType.DOT, source.charAt(index)); // System.out.println("DOT"); break; case '\': result = new Token(TokenType.LAMBDA, source.charAt(index)); // System.out.println("LAMBDA"); break; case '(': result = new Token(TokenType.LPAREN, source.charAt(index)); // System.out.println("LPAREN"); break; case ')': result = new Token(TokenType.RPAREN, source.charAt(index)); // System.out.println("RPAREN"); break; case ' ': result = new Token(TokenType.BLANK, source.charAt(index)); break; default: if ('a' <= source.charAt(index) && source.charAt(index) <= 'z') { int temp = index + 1; while (temp < source.length() && (('a' <= source.charAt(temp) && source.charAt(temp) <= 'z') || ('A' <= source.charAt(temp) && source.charAt(temp) <= 'Z'|| ('0' <= source.charAt(temp) && source.charAt(temp) <= '9')))) temp++; result = new Token(TokenType.LCID, source.substring(index, temp)); // System.out.println("LCID"); } else { result = new Token(TokenType.EOF, ""); // System.out.println("EOF"); } } } else { result = new Token(TokenType.EOF, ""); System.out.println("EOF"); hasEnd = true; } } else result = new Token(TokenType.EOF, ""); return result; }
首先可以看到在方法内部存在大量的重复代码,可以将这些代码提取出来作为一个独立的方法。比如将 "result = new Token(TokenType.EOF, "");" 提取出来,放到一个独立的方法中,这样会使代码更加简洁易懂。
其次,可以使用一个 HashMap 来存储字符与对应的 TokenType,这样可以避免使用大量的 switch-case 语句,提高代码的可读性和可维护性。
最后,可以将一些重复的逻辑提取出来,比如判断字符是否为字母或数字的逻辑可以提取出来作为一个方法,这样可以减少代码重复。
下面是优化后的代码:
```
private Token nextToken() {
if (hasEnd) {
return new Token(TokenType.EOF, "");
}
if (index >= source.length()) {
hasEnd = true;
return new Token(TokenType.EOF, "");
}
char ch = source.charAt(index);
if (ch == ' ') {
index++;
return nextToken();
}
if (TOKEN_MAP.containsKey(ch)) {
TokenType type = TOKEN_MAP.get(ch);
index++;
return new Token(type, ch);
} else if (isLetterOrDigit(ch)) {
int temp = index + 1;
while (temp < source.length() && isLetterOrDigit(source.charAt(temp))) {
temp++;
}
String value = source.substring(index, temp);
index = temp;
return new Token(TokenType.LCID, value);
} else {
hasEnd = true;
return new Token(TokenType.EOF, "");
}
}
private boolean isLetterOrDigit(char ch) {
return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ('0' <= ch && ch <= '9');
}
private static final Map<Character, TokenType> TOKEN_MAP = new HashMap<>();
static {
TOKEN_MAP.put('.', TokenType.DOT);
TOKEN_MAP.put('\\', TokenType.LAMBDA);
TOKEN_MAP.put('(', TokenType.LPAREN);
TOKEN_MAP.put(')', TokenType.RPAREN);
}
```
相关推荐
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![docx](https://img-home.csdnimg.cn/images/20210720083331.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)