10
votes

Utilisation du modèle d'interprète sur une structure composite

J'ai été demandé de faire un évaluateur d'expression en utilisant Composite em>, récursive Descendent Parser em> et Interprète em>.

Voici le grammaire strong>: p>

<cond> → <termb> [OR <termb>]*
<termb>→<factb>[AND <factb>]*
<factb>→<expr> RELOP <expr> | NOT <factb> | OPAR <cond> CPAR
<expr> → [PLUS | MINUS] <term> [(PLUS <term>) | (MINUS <term>)]*
<term> → <termp> [(MULT <termp>) | (DIV <termp>) | (REM <termp>)]*
<termp> → <fact> [POWER <fact>]*
<fact> → ID | NUM | OPAR1 <expr> CPAR1
----TERMINALS----
ID → ("A" | ... | "Z" | "a" | ...| "z") [("A"| ... | "Z" | "a" | ...| "z" | "0" | ... | "9")]*
NUM → ("0" | ... | "9") [("0" | ... | "9")]*
OPAR → "("
CPAR → ")"
OPAR1 → "["
CPAR1 → "]"
RELOP → EQ | NEQ | GT | GE | LT | LE
EQ → "= ="
NEQ → "!="
GT → ">"
GE → ">="
LT → "<"
LE → "<="
POWER → "^"
DIV → "/"
REM → "%"
MULT → "*"
MINUS → "−"
PLUS → "+"
AND → “and” or “&&”
OR → “or” or “||”
NOT → “not” or “!”


0 commentaires

3 Réponses :


3
votes

Si je comprends bien votre problème, je dirais que chaque classe de béton doit par une sous-classe de votre structure composite principale.

Si l'expression est votre composite principal alors:

expression: terme Expression: Operandterm

condition: expression binoperand terme Condition: expression unyopérande

Terme: int | Foom | ...

. . .


0 commentaires

2
votes

the Interprète vous permet de définir une expression de votre langue basée sur le terminal et pas d'objets terminaux. Un interprète est un modèle composite lui-même, donc je pense que c'est déjà appliqué.

Peut-être que vous n'avez pas besoin de créer une classe par élément noterminal et de terminal, utilisez des attributs tels que (OperatorType, ExpressType) dans des classes non traitantes / bornes différentes de vos symboles de grammaire.

donné et expression générée avec votre grammaire comme [A = 0], l'arbre d'objets formé avec des classes de motif d'interpréteur ressemblera à ceci (pardonnez-vous pour la mauvaise qualité et les erreurs UML Sintax, mais je n'ai pas maintenant un éditeur UML approprié ):

Entrez la description de l'image ici

Cet arborescence d'objet doit être construit par un analyseur d'expression. Une fois que vous avez cet arbre, utilisez l'analyseur descendant récursif pour marcher sur cet arbre évaluant chaque nœud d'arbres.

Ainsi, l'évaluation de l'expression est faite par l'analyseur et l'interprète vous fournit une structure de données pour représenter vos expressions de grammaire.

J'espère que cette aide.


0 commentaires

11
votes

Je ne sais pas pourquoi on vous a dit de ne pas utiliser la même structure arborescente. Je pense que j'ajouterais une méthode d'évaluation () à mon interface d'expression. Ça me semble logique. Une expression devrait savoir comment s'évaluer.

Je dirais que votre interface d'expression actuelle expose trop (telles que les opérandes). En tant que client d'expression, je n'aurais besoin que de 1) invoquer et 2) lire le résultat et je suppose peut-être que 3) l'avoir imprimé. En fait, je préférerais utiliser la touche () sur l'impression directe () sur l'impression directe.

Vous avez probablement déjà remarqué que toutes les expressions ne prennent pas 2 opérandes (telles que non ni négativement). Cela crée déjà une sorte de divergence avec votre interface. Je le simplifierais à: xxx

puis chacun de vos opérations et de ces terminaux sait comment s'évaluer (et se convertir en chaîne).

Donc, je pourrais avoir des opérations en béton comme: xxx

maintenant je peux construire l'arborescence assez facilement xxx

et je ne peux pas t même besoin d'un accès direct à des opérandes individuels.


1 commentaires

C'est fondamentalement ce que je pensais du début, mais je devrais peut-être arrêter de faire confiance aux personnes qui donnent des conseils sans savoir ce qu'ils parlent!