我的词法分析器可以识别数字 (5,555,543667)、小数 (44.65,4.1) 和句点 (.)。
我可以很好地计算数字、小数和句点,但是当我遇到一个数字和一个句点彼此相邻时,它会将其计为小数。
考虑包含以下内容的文本文件:555 2.3 55.23 44 5。
我的输出是
1 类型 1:555
2型3:2.3
3 型 3:55.23
4 类型 1: 44
5 类型 3:5。
其中类型 3 是我的小数标识符。
我希望将第 5 个和第 6 个标记计为数字,然后计为句点。
这是我处理 switch 语句的方式。
switch(*b) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
digits:
t.length++;
switch(*(b + t.length)) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
goto digits;
case '.':
goto decimal;
break;
default:
break;
}
t.type = TOKEN_DIGITS;
t.string = (char *)calloc(t.length + 1, sizeof(char));
strncpy(t.string, b, t.length);
break;
decimal:
t.length++;
switch(*(b + t.length)) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
goto decimal;
break;
}
t.type = TOKEN_DECIMAL;
t.string = (char *)calloc(t.length+1,sizeof(char));
strncpy(t.string,b,t.length);
break;
尝试了很多东西,但我正式卡住了。
最佳答案
你真的应该使用 character classification functions对于这种练习而不是长 switch 语句。您的代码会简单很多,您根本不必使用 goto
。
例如,可以使用以下正则表达式来描述一个数字(添加空格以分解各个 block ):
[-+]? [0-9]* \.? [0-9]+
这已经显示了可能的状态转换:
- 数字可以(可选)以
+
或-
开头(如果您支持签名数字) - 它可能有 0..n 位
- 如果后面的字符不是小数点符号,则应为分隔符,否则为无效符号。如果它是分隔符,您的号码将被终止。
- 小数点后应有1..n位
- 当您到达输入末尾或遇到分隔符时,该数字将终止
所有这些都可以在几行代码中完成 - 只需有一个指向您当前输入字符的指针,然后继续逐个向前检查每个字符,并根据字符类决定要做什么.
现在,这种特殊方法不使用科学记数法等处理 float ,但是一旦您完成了基础知识,添加这些额外内容就非常简单。
关于C词法分析器。使用开关分析和计算小数/非小数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19329474/