gpt4 book ai didi

java - 字符串表达式解析技巧?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:11:45 25 4
gpt4 key购买 nike

今年假期我很无聊,随机决定为 Java 编写一个简单的列表理解/过滤库(我知道那里有一些很棒的库,我只是想自己写一个).

对于这个列表:

LinkedList<Person> list = new LinkedList<Person>();
list.add(new Person("Jack", 20));
list.add(new Person("Liz", 58));
list.add(new Person("Bob", 33));

语法是:

Iterable<Person> filtered = Query.from(list).where(
Condition.ensure("Age", Op.GreaterEqual, 21)
.and(Condition.ensure("Age", Op.LessEqual, 50));

我知道它很丑,但如果我使用静态导入并使用较短的方法名称,它就会变得非常简洁。

以下语法是最终目标:

Iterable<Person> list2 = Query.from(list).where("x=> x.Age >= 21 & x.Age <= 50");

显然表达式解析不是我的强项,我在解析嵌套/多个条件时遇到了麻烦。有人知道我可能会觉得有用的一些资源/文献吗?

目前我只有一个条件表达式从 String lambda 语法中成功解析:"x=> x.Name == Jack"。我的底层表达式结构相当可靠,可以轻松处理任何数量的嵌套,问题只是从字符串解析表达式。

谢谢

只是为了好玩,这里是关于幕后表达式结构如何工作的一些见解(显然我可以在下面的示例中指定'op.GreaterEqual'等......但我想演示如何它对任何数量的嵌套都很灵活):

Condition minAge1 = Condition.ensure("Age", Op.Equal, 20);
Condition minAge2 = Condition.ensure("Age", Op.Greater, 20);
Expression minAge = new Expression(minAge1, Express.Or, minAge2);
Expression maxAge = Condition.ensure("Age", Op.Equal, 50).or(Condition.ensure("Age", Op.Less, 50));
Expression ageExpression = new Expression(minAge, Express.And, maxAge);

Condition randomException = Condition.ensure("Name", Op.Equal, "Liz");
Expression expressionFinal = new Expression(ageExpression, Express.Or, randomException);

最佳答案

基本上您需要的是 recursive descent parser对于表达式。这是编译器理论中的一个重要主题,因此任何有关编译器的书籍都会涵盖该主题。在正式的语法术语中,它看起来像这样:

condition  : orAtom ('||' orAtom)+ ;
orAtom : atom ('&&' atom)+ ;
atom : '(' condition ')'
| expression ;
expression : value OPER value ;
value : VARIABLE | LITERAL '
VARIABLE : (LETTER | '_') (LETTER | DIGIT | '_')* ;
LITERAL : NUMBER
| STRING ;
NUMBER : '-'? DIGIT+ ('.' DIGIT+)? ;
STRING : '"' . CHAR* . '"' '
CHAR : ('\\' | '\"' | .) + ;
LETTER : 'a'..'z' | 'A'..'Z' ;
DIGIT : '0'..'9' ;
OPER : '>' | '>=' | '<' | '<=' | '=' | '!=' ;

上面的语法(大部分)在ANTLR中形成我最熟悉的形式。

解析 boolean 或算术表达式是处理解析时的经典介绍性主题,因此您应该能够找到大量关于它的文献。如果您想学习 ANTLR(因为您使用的是 Java),我强烈建议您阅读 The Definitive ANTLR Reference: Building Domain-Specific Languages .

如果这一切看起来有点矫枉过正,需要接受的东西太多,那么您可能是对的。这是一个很难开始的话题。

您的另一种选择是不创建任意字符串表达式,而是使用流畅的界面(就像您正在做的那样):

List results = from(source)
.where(var("x").greaterThan(25), var("x").lessThan(50))
.select("field1", "field2");

因为这是在代码中说明表达式树,应该更容易实现。

关于java - 字符串表达式解析技巧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2080354/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com