所以,我需要为作业编写一个编译器扫描器,并认为使用正则表达式会很“优雅”。事实是,我之前很少使用它们,而且已经很久了。所以我忘记了大部分关于它们的东西,需要四处看看。我已经成功地将它们用于标识符(或者至少我认为是这样,我仍然需要进行一些进一步的测试,但现在它们看起来都还不错),但是我在数字识别方面遇到了问题。
函数nextCh()
读取输入上的下一个字符(向前看字符)。我想在这里做的是检查这个字符是否匹配正则表达式[0-9]*
。我将每个匹配的字符附加到当前标记的str
字段中,然后读取此字段的int值。它可以识别单个数字输入,例如“123”,但我遇到的问题是对于输入“123 456”,最终的str
将是“123 456”,而我应该得到两个具有字段“123”和“456”的单独标记。为什么会匹配“ ”?
private void readNumber(Token t) {
t.str = "" + ch; // force conversion char --> String
final Pattern pattern = Pattern.compile("[0-9]*");
nextCh(); // get next char and check if it is a digit
Matcher match = pattern.matcher("" + ch);
while (match.find() && ch != EOF) {
t.str += ch;
nextCh();
match = pattern.matcher("" + ch);
}
t.kind = Kind.number;
try {
int value = Integer.parseInt(t.str);
t.val = value;
} catch(NumberFormatException e) {
error(t, Message.BIG_NUM, t.str);
}
谢谢!
PS:我使用以下代码解决了我的问题。然而,我想理解我的正则表达式中的缺陷在哪里。
t.str = "" + ch;
nextCh(); // get next char and check if it is a number
while (ch>='0' && ch<='9') {
t.str += ch;
nextCh();
}
t.kind = Kind.number;
try {
int value = Integer.parseInt(t.str);
t.val = value;
} catch(NumberFormatException e) {
error(t, Message.BIG_NUM, t.str);
}
编辑:事实证明,我的正则表达式也无法识别标识符(仍然包括空格),所以我不得不转而使用类似于我的“解决方案”的系统(带有许多条件)。看来我需要重新学习正则表达式:O
^
表示字符串将从开头匹配。$
表示从结尾匹配。因此,如果你在正则表达式两侧使用^
和$
,就意味着该字符串必须完全匹配。如果没有它们,像' rdpa5'
这样的字符串会与'5'
一样匹配,因为有一个数字出现在字符串中某个地方。当然,如果你只是每次比较单个字符,我认为这些语句结构不会有太大区别。 - David John WelshMatcher
方法是错误的。请看我的答案。 - Ian McLaird