我正在研究词法分析器,这是构建编译器的第一步。给定.txt文件,代码必须标识每个词法组件,例如,如果我有
String c = "abcdefg";
必须打印
String -> type
c -> variable
= -> assignment operator
"abcdefg" -> constant String
; -> Delimit
但如果我有这样的事情:
String c = "abc
d"; System.out.println("*");
编译会说:字符串文字没有被双引号正确关闭。但是java编译器如何使用另一个语句System.out.println(“*”);它必须忽略它,还是必须识别它的元素?
答案 0 :(得分:2)
你的问题的结论是:
但是java编译器如何使用另一个语句System.out.println(“*”);它必须忽略它,还是必须识别它的元素?
首先,尝试一下,看看Java编译器在这样的示例中实际给出的错误消息。 (显然,您需要调整测试用例以隔离对特定情况的处理......)
您很可能会发现编译器没有完成恢复工作。我希望处理未在行尾关闭的字符串的策略是假设字符串文字已关闭并在非引用模式下继续“lexing”。但在你的例子中,这可能会给出进一步的错误。
这让我想到了第二点。我建议你不要过于努力从词汇错误中恢复过来。专注于让词法分析器/编译器在输入有效的情况下工作。您可以随时恢复错误恢复的改进......当您有更重要的事情正常工作时。
(@ EJP的评论很明显。“重型”错误恢复通常在解析器级别完成,而不是词法分析器级别。)
最后:您的要求:
String c = "abcdefg";
必须打印
String -> type c -> variable = -> assignment operator "abcdefg" -> constant String ; -> Delimit
如果要解析真正的Java,那么(纯粹的)词法分析器就无法做到这一点。问题是无法确定String
是一个类型(或应该是一个类型),而a
是词法分析器中的变量名(或应该是变量名)。实际上,如果你忽略了语法上下文(通常不适用于词法分析器!)那么String
可以是各种各样的东西,包括类名,包名,方法名,字段名,局部变量名等等。
处理这种情况的正常方法是让词法分析器将String
和a
都视为“标识符”...并将其留给解析器和/或语义分析器进行排序它出来了。