Lab1 Lexer 编写 SysYLexer.g4
官方文档
然后 make compile
生成相应的词法分析器
需要注意的是数字的匹配:
输出时忽略所有注释,对十六进制和八进制数字常量输出token文本时需输出其十进制的值
提示:八进制和十六进制整型常量支持前导0。遇到如 int x = 0002;
和int y = 0x00003;
这种输入时,请将 0002
和0x00003
分别识别为十进制整型常量2
和3
。
特别注意,遇到如int 2i = 08;
这种输入时,请将2i
识别为INTEGER_CONST
和IDENT
,08
识别为两个INTEGER_CONST
,这种我们不认为是词法错误,这种错误将在后面的实验中处理
正则:
1 2 3 4 5 6 INTEGER_CONST : [1-9][0-9]* |'0'[0]*[1-7][0-7]* |'0'[xX][0]*[1-9a-fA-F][0-9a-fA-F]* |'0' ;
相应的转换:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 for (Token token : myTokens) { String text = token.getText(); if (token.getType() == SysYLexer.INTEGER_CONST) { if (text.equals("0" )) { ; } else if (text.startsWith("0x" ) || text.startsWith("0X" )) { int val = Integer.parseInt(text.substring(2 ), 16 ); text = String.valueOf(val); } else if (text.startsWith("0" )) { int val = Integer.parseInt(text.substring(1 ), 8 ); text = String.valueOf(val); } } System.err.println(vocabulary.getSymbolicName(token.getType()) + " " + text + " at Line " + token.getLine() + "." ); }
正则的顺序问题似乎没有影响,应该 Antlr 会解决例如 ==
和 =
的匹配问题。
第二三四步按文档抄上去就行了
ErrorListener
参考资料
看了看源码大概是这样写的,不过机制没有太看懂= =
1 2 3 4 5 6 7 8 9 10 11 public class myErrorListener extends BaseErrorListener { boolean hasError = false ; public myErrorListener () { super (); } public void syntaxError (Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) { this .hasError = true ; System.err.println("Error type A at Line " + line + ":" + msg); } }