带十进制数的词法分析器
Lexical analyzer with decimal numbers
我正在尝试编写一个非常基本的文本处理器。目标是逐个字符地从文件中读取并确定它是什么类型的标记。基本上我所做的是将所有字符加载到队列中,并使用 peek() 和 read() 检查顶部元素是否(对于这部分)是一个数字,如果它附加到一个字符串,它将用作不同符号的哈希映射中的键。
按以下方法发布。当 peek() 看到一个数字时,char 与队列一起传递给此方法以进行进一步处理。我遇到的问题是,当我开始构建数字(作为字符串)时,我使用带有正则表达式的 java matches() 来仅匹配 0-9 的数字,否则该方法应该停止构建字符串和 return 词位对象。
但这就是我的问题所在。例如,在读取 4 和 2 之后,它会不断添加队列中的所有字符,直到它为空——并将它们全部集中在数字下而不是创建新标记。
任何指导将不胜感激。我有点被困在这里。
我的输入:
美国广播公司 := 42 ;
EOF
代码:
/**
*
* @param - cl ADT containing each character as read from a file
* @param - c current head of the ADT
* @return - lexeme 3 tuple that holds the keyword "number", the token read in, and the value 19
*/
public static Lexeme isNumber(CharQue<Character> cl, char c){
Lexeme lexeme = new Lexeme();
while (String.valueOf(c).matches("[0-9]") && (cl.hasNext())) {
if (String.valueOf(c).matches("[0-9]")) {
lexeme.buildKey(cl.read());
} else if(c =='.'){
lexeme.buildKey(c);
c = cl.peek();
break;
}
}
while(String.valueOf(c).matches("[0-9]") && (cl.hasNext())){
c = cl.read();
if (String.valueOf(c).matches("[0-9]")) {
lexeme.buildKey(c);
}
}
lexeme.setTokken(lexeme.getKey());
lexeme.setKey(NUMBER);
return lexeme;
}
结果:在一个 3 元组中(关键字、读入的内容、分配给该关键字的值)。
(关键字、令牌读取、值)
----------------------
(标识符,ABC,28)
(SPACE, , 26)
(:=, , 24)
(SPACE, , 26)
(数字, 42 ;EOF, 29)
期望的输出:
(关键字、令牌、值)
(identifier, ABC, 28)
(SPACE, , 26)
(:=, , 24)
(SPACE, , 26)
(number, 42, 29)
( ;, , 25)
(EOF, , 31)
我认为您在用尽所有输入之前不会退出第一个循环。 c
永远不会更新(除了在 else if
中,它永远不会被调用)。在你的程序结束时 c
仍然等于 '4'
.
作为解决方案的一般路径,您可能应该检查 peek()
的值是否是可接受的值。这样,如果是,您就拨打cl.read()
,如果不是,您的号码就结束了。
我正在尝试编写一个非常基本的文本处理器。目标是逐个字符地从文件中读取并确定它是什么类型的标记。基本上我所做的是将所有字符加载到队列中,并使用 peek() 和 read() 检查顶部元素是否(对于这部分)是一个数字,如果它附加到一个字符串,它将用作不同符号的哈希映射中的键。
按以下方法发布。当 peek() 看到一个数字时,char 与队列一起传递给此方法以进行进一步处理。我遇到的问题是,当我开始构建数字(作为字符串)时,我使用带有正则表达式的 java matches() 来仅匹配 0-9 的数字,否则该方法应该停止构建字符串和 return 词位对象。
但这就是我的问题所在。例如,在读取 4 和 2 之后,它会不断添加队列中的所有字符,直到它为空——并将它们全部集中在数字下而不是创建新标记。
任何指导将不胜感激。我有点被困在这里。
我的输入: 美国广播公司 := 42 ; EOF
代码:
/**
*
* @param - cl ADT containing each character as read from a file
* @param - c current head of the ADT
* @return - lexeme 3 tuple that holds the keyword "number", the token read in, and the value 19
*/
public static Lexeme isNumber(CharQue<Character> cl, char c){
Lexeme lexeme = new Lexeme();
while (String.valueOf(c).matches("[0-9]") && (cl.hasNext())) {
if (String.valueOf(c).matches("[0-9]")) {
lexeme.buildKey(cl.read());
} else if(c =='.'){
lexeme.buildKey(c);
c = cl.peek();
break;
}
}
while(String.valueOf(c).matches("[0-9]") && (cl.hasNext())){
c = cl.read();
if (String.valueOf(c).matches("[0-9]")) {
lexeme.buildKey(c);
}
}
lexeme.setTokken(lexeme.getKey());
lexeme.setKey(NUMBER);
return lexeme;
}
结果:在一个 3 元组中(关键字、读入的内容、分配给该关键字的值)。 (关键字、令牌读取、值) ---------------------- (标识符,ABC,28) (SPACE, , 26) (:=, , 24) (SPACE, , 26) (数字, 42 ;EOF, 29)
期望的输出: (关键字、令牌、值)
(identifier, ABC, 28)
(SPACE, , 26)
(:=, , 24)
(SPACE, , 26)
(number, 42, 29)
( ;, , 25)
(EOF, , 31)
我认为您在用尽所有输入之前不会退出第一个循环。 c
永远不会更新(除了在 else if
中,它永远不会被调用)。在你的程序结束时 c
仍然等于 '4'
.
作为解决方案的一般路径,您可能应该检查 peek()
的值是否是可接受的值。这样,如果是,您就拨打cl.read()
,如果不是,您的号码就结束了。