我必须使用Java编写一个Lexer方言的Lexer代码。
我将Enum中的所有TokenType分组
public enum TokenType {
INT("-?[0-9]+"),
BOOLEAN("(TRUE|FALSE)"),
PLUS("\\+"),
MINUS("\\-"),
//others.....
}
名称是TokenType名称,括号中有我用来匹配Type的正则表达式。
如果我想匹配INT类型我使用“ - ?[0-9] +”。
但现在我有一个问题。我将TokenType的所有正则表达式放入StringBuffer中:
private String pattern() {
StringBuffer tokenPatternsBuffer = new StringBuffer();
for(TokenType token : TokenType.values())
tokenPatternsBuffer.append("|(?<" + token.name() + ">" + token.getPattern() + ")");
String tokenPatternsString = tokenPatternsBuffer.toString().substring(1);
return tokenPatternsString;
}
所以它返回一个像:
这样的字符串(?<INT>-?[0-9]+)|(?<BOOLEAN>(TRUE|FALSE))|(?<PLUS>\+)|(?<MINUS>\-)|(?<PRINT>PRINT)....
现在我用这个字符串来创建一个Pattern
Pattern pattern = Pattern.compile(STRING);
然后我创建了一个Matcher
Matcher match = pattern.match("line of code");
现在我想匹配所有TokenType并将它们分组到Token的ArrayList中。如果代码语法正确,则返回Token的ArrayList(令牌名称,值)。
但我不知道如果语法错误然后打印错误,如何退出while循环
这是用于创建令牌的ArrayList的一段代码。
private void lex() {
ArrayList<Token> tokens = new ArrayList<Token>();
int tokenSize = TokenType.values().length;
int counter = 0;
//Iterate over the arrayLinee (ArrayList of String) to get matches of pattern
for(String linea : arrayLinee) {
counter = 0;
Matcher match = pattern.matcher(linea);
while(match.find()) {
System.out.println(match.group(1));
counter = 0;
for(TokenType token : TokenType.values()) {
counter++;
if(match.group(token.name()) != null) {
tokens.add(new Token(token , match.group(token.name())));
counter = 0;
continue;
}
}
if(counter==tokenSize) {
System.out.println("Syntax Error in line : " + linea);
break;
}
}
tokenList.add("EOL");
}
}
如果for循环遍历所有TokenType并且与TokenType的任何正则表达式都不匹配,则代码不会中断。如果语法不正确,如何返回错误?
或者您知道在哪里可以找到有关开发词法分析器的信息吗?
答案 0 :(得分:1)
如果您使用的是Java,我建议您尝试ANTLR 4来创建词法分析器。语法语法比正则表达式更清晰,从语法生成的词法分析器将自动支持报告语法错误。
答案 1 :(得分:1)
您需要做的就是添加额外的&#34; INVALID&#34;你的枚举类型末尾的标记,带有#34;。+&#34;等正则表达式。 (匹配一切)。由于正则表达式按顺序进行评估,因此只有在找不到其他标记时才会匹配。然后,检查列表中的最后一个令牌是否为INVALID令牌。
答案 2 :(得分:0)
如果您正在编写完整的词法分析器,我建议使用现有的语法构建器。 Antlr是一个解决方案,但我个人推荐使用parboiled,它允许用纯Java编写语法。
答案 3 :(得分:0)
不确定这是否得到了回答,或者您得到了答案,但词法分析器分为两个不同的阶段,即扫描阶段和解析阶段。您可以将它们组合成一个单一的传递(正则表达式匹配),但是如果您需要执行除最基本的字符串翻译之外的任何操作,您将发现单个传递词法分析器存在缺陷。
在扫描阶段,您可以根据您指定的特定令牌将字符序列分开。您应该做的是包含您尝试解析的文本的示例。但Wiki has a great example简单的文本词法分析器将句子变为标记(例如str.split(&#39;&#39;))。因此,使用扫描仪,您将通过空格将文本块标记为块(这应该是几乎总是第一个动作),然后您将基于其他标记进一步进行标记化,例如什么你试图匹配。
然后,解析/评估阶段将迭代每个令牌,并根据业务逻辑,语法规则等决定如何处理每个令牌,无论您设置它。这可以表达某种数学函数来执行(例如,max(3,2)),或者更常见的例子是用于查询语言构建。您可以创建一个具有特定查询语言的Web应用程序(SOLR,以及任何SQL / NoSQL DB),该应用程序被翻译成另一种语言以对数据源发出请求。 Lexer通常也在IDE中用于代码提示和自动完成。
这不是一个基于代码的答案,但它的答案可以让您了解如何解决问题。