Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Java编写的带正则表达式的基本Lexer_Java_Regex_Token_Lexer - Fatal编程技术网

用Java编写的带正则表达式的基本Lexer

用Java编写的带正则表达式的基本Lexer,java,regex,token,lexer,Java,Regex,Token,Lexer,我必须用Java为BASIC方言编写一个Lexer 我将枚举中的所有标记类型分组 公共枚举令牌类型{ INT(“-?[0-9]+”), 布尔值((真|假)), 加上(\\+), 减去(\\-”, //其他。。。。。 } 名称是TokenType名称,括号中是我用来匹配该类型的正则表达式 如果我想匹配INT类型,我使用“-?[0-9]+” 但现在我有一个问题。我将TokenType的所有正则表达式放入一个StringBuffer中,如下所示: 私有字符串模式(){ StringBuffer to

我必须用Java为BASIC方言编写一个Lexer
我将枚举中的所有标记类型分组

公共枚举令牌类型{
INT(“-?[0-9]+”),
布尔值((真|假)),
加上(\\+),
减去(\\-”,
//其他。。。。。
}
名称是TokenType名称,括号中是我用来匹配该类型的正则表达式
如果我想匹配INT类型,我使用“-?[0-9]+”

但现在我有一个问题。我将TokenType的所有正则表达式放入一个StringBuffer中,如下所示:

私有字符串模式(){
StringBuffer tokenPatternsBuffer=新StringBuffer();
for(TokenType标记:TokenType.values())
tokenPatternsBuffer.append(“|”(?“+token.getPattern()+”);
字符串tokenPatternsString=tokenPatternsBuffer.toString().substring(1);
返回令牌模式字符串;
}
因此它返回一个字符串,如下所示:

(?<INT>-?[0-9]+)|(?<BOOLEAN>(TRUE|FALSE))|(?<PLUS>\+)|(?<MINUS>\-)|(?<PRINT>PRINT)....
然后我创建一个匹配器

现在我想匹配所有的令牌类型,并将它们分组到令牌的ArrayList中。如果代码语法正确,它将返回令牌(令牌名称、值)的ArrayList
但是如果语法不正确,我不知道如何退出while循环,然后打印错误。
这是一段代码,用于创建令牌的ArrayList。

private void lex(){
ArrayList标记=新的ArrayList();
int tokenSize=TokenType.values().length;
int计数器=0;
//迭代arrayLinee(字符串的ArrayList)以获得模式的匹配
用于(字符串线性A:arrayLinee){
计数器=0;
匹配器匹配=模式匹配器(linea);
while(match.find()){
系统输出println(匹配组(1));
计数器=0;
for(TokenType标记:TokenType.values()){
计数器++;
if(match.group(token.name())!=null){
添加(新令牌(令牌,match.group(Token.name()));
计数器=0;
继续;
}
}
如果(计数器==令牌大小){
System.out.println(“行中的语法错误:“+linea”);
打破
}
}
标记列表。添加(“EOL”);
}
}
如果for循环迭代所有TokenType并且不匹配TokenType的任何正则表达式,则代码不会中断。如果语法不正确,如何返回错误

或者你知道我在哪里可以找到关于开发lexer的信息吗?

如果你在Java中工作,我建议尝试创建lexer。语法语法比正则表达式干净得多,从语法生成的lexer将自动支持报告语法错误。

如果要编写完整的lexer,我建议使用现有的语法生成器。Antlr是一种解决方案,但我个人推荐使用它,它允许用纯Java编写语法。

您需要做的就是在枚举类型的末尾添加一个额外的“无效”标记,并使用类似“+”(匹配所有内容)的正则表达式。因为正则表达式是按顺序计算的,所以只有在找不到其他令牌时才会匹配。然后检查列表中的最后一个标记是否为无效标记。

不确定这是否得到了回答,或者您找到了答案,但lexer被分为两个不同的阶段,扫描阶段和解析阶段。您可以将它们组合成一个单过程(正则表达式匹配),但是如果您需要做的不是最基本的字符串转换,那么您会发现单过程lexer有缺点

在扫描阶段,根据指定的特定标记将字符序列分开。您应该做的是包含一个您试图解析的文本示例。但是一个简单的文本词法,它将一个句子转换成标记(例如str.split(“”))。因此,使用扫描器,您将按空格将文本块标记为块(这几乎总是第一个操作),然后您将根据其他标记(例如您尝试匹配的标记)进一步标记

然后,解析/评估阶段将迭代每个令牌,并根据业务逻辑、语法规则等决定如何处理每个令牌,不管您设置了什么。这可以表示某种要执行的数学函数(例如max(3,2)),或者更常见的示例是查询语言构建。您可以制作一个web应用程序,该应用程序具有一种特定的查询语言(我想到的是SOLR,以及任何SQL/NoSQL DB),该语言被翻译成另一种语言,以针对数据源发出请求。lexer通常用于IDE中的代码暗示和自动完成


这不是一个基于代码的答案,但它应该能让您了解如何解决这个问题。

这是一个大学项目,我不能使用Java之外的其他库或工具。:(这就是为什么我必须为BASIC方言编写整个Lexer和解析器的原因。这是一个大学项目,我不能使用Java之外的其他库或工具。)(这就是为什么我必须为BASIC方言编写整个Lexer和解析器的原因。
Pattern pattern = Pattern.compile(STRING);
Matcher match = pattern.match("line of code");
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");
     }
}