6
votes

EXPRESSION DE STRING PARSING CONSEILS?

Je me suis ennuyé pendant la saison des vacances cette année et j'ai décidé de manière aléatoire d'écrire une bibliothèque de compréhension / filtrage de la liste simple pour Java (je sais qu'il y en a d'excellents là-bas, je voulais juste m'écrire moi-même pour l'enfer ).

pour cette liste: xxx

syntaxe est: xxx

Je connais sa laid, mais si je Utilisez des importations statiques et utilisez des noms de méthodes plus courts qu'il devient assez concis.

La syntaxe suivante est l'objectif ultime: xxx

apparemment l'analyse de l'expression n'est pas mon plus fort Zone, j'ai du mal à analyser des conditionnels imbriqués / multiples. Quelqu'un sache de certaines ressources / littérature, je pourrais trouver utile?

Je n'ai que des expressions conditionnelles simples étant sans succès à la String Lambda Syntax pour le moment: "x => x.name == Jack ". Ma structure d'expression sous-jacente est relativement solide et peut facilement gérer n'importe quelle quantité d'imbrication, le problème n'est que l'expression d'une analyse d'une chaîne.

merci

juste pour des coups de pied, voici un peu Insight sur la manière dont la structure d'expression derrière les scènes peut fonctionner (évidemment, j'aurais pu spécifier «Op.Greatequal», etc. Dans l'exemple suivant, mais je voulais démontrer comment il est flexible à toute quantité de nidification): < / p> xxx


3 commentaires

"x => x.age> = 21 & x.age <= 50" ne pas analyser pour moi: Pourriez-vous le préciser? Il y a trois expressions devant le & , qui est très différente des clauses de style Vanilla SQL.


Je n'ai pas l'intention d'écrire un fournisseur pour lier mes utilitaires jusqu'à une base de données relationnelle, bien que cela puisse être amusant. Exactement, qu'est-ce que tu me demandes d'élaborer?


@Chii: je pense, "x => x.age> = 21 & x.age <= 50" équivaut à une fonction anonyme qui prend un argument x et retourne vrai ou faux en évaluant l'expression à droite du " => '' Opérateur.


3 Réponses :


5
votes

Fondamentalement ce que vous voudrez, c'est un analyseur de descente récursive pour les expressions. C'est un sujet très présenté dans la théorie du compilateur afin que tout livre sur les compilateurs couvrira le sujet. En termes de grammaire formels, il ressemblera à quelque chose comme ceci:

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


2 commentaires

Je pensais que le royaume que je cherchais. Merci un tas, au moins j'ai un point de départ maintenant.


Je ne dis pas que ma mise en œuvre actuelle est terminée, mais elle peut gérer tout ce que j'ai pu y jeter jusqu'à présent. Cela nécessite des travaux sur le côté de l'efficacité. Je pense vraiment que le seul moyen de réduire la verbosité au point que je serai satisfait de la mise en œuvre de la chaîne (qui sera analysée à la même structure d'expression sous-jacente IM en utilisant maintenant).



1
votes

Pour ajouter à la réponse clote, vous voudrez d'abord définir votre grammer.

L'expression suivante des grammer fonctionne assez bien pour la plupart des cas, malheureusement, une descente récursive normale ne vous permet pas de définir la partie récursive d'abord dans chaque production. Cela vous ferait appeler la méthode de production de manière récursive jusqu'à ce que vous obteniez un débordement de pile. P>

 private MyExpression parseOr(MyScanner scanner) {
        MyExpression expression = null;

        MyExpression rightExpr = parseAnd(scanner);
        Token token = scanner.getCurrentToken();
        if (token.hasValue("|") {
            expression = new MyExpression();
            expression.setOperator(OR);
            Token nextToken = scanner.getNextToken(); // remember, this is scanning in reverse
            MyExpression leftExpression = parseOr(scanner);
            expression.setLeft(leftExpression);
            expression.setRight(rightExpression);
        }
        else {
            expression = rightExpression;
        }
        return expression;
    } 


0 commentaires

1
votes

Merci pour tous les gars de pointe. J'ai décidé que la plupart de cela était bien plus que nécessaire, alors j'ai fini par expulser le enfer pour obtenir des choses à des groupes gérables que je pouvais facilement analyser dans 20-30 lignes de code.

ive obtenu l'interface de chaîne lambdaexpression fonctionner presque ainsi que l'interface fluide, un ou deux petits bugs.

Je vais probablement continuer à le développer un peu juste pour le plaisir, mais il est évidemment trop inefficace pour vraiment utiliser depuis environ 90% de réflexion.


0 commentaires