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 â!â
3 Réponses :
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. P>
Si l'expression est votre composite principal alors: p>
expression: terme Expression: Operandterm P>
condition: expression binoperand terme Condition: expression unyopérande p>
Terme: int | Foom | ... p>
. . . p>
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é. P>
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. p>
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é ): p>
p>
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. P>
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. P>
J'espère que cette aide. P>
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. P>
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 à: p> puis chacun de vos opérations et de ces terminaux sait comment s'évaluer (et se convertir en chaîne). P> Donc, je pourrais avoir des opérations en béton comme: p> maintenant je peux construire l'arborescence assez facilement p> et je ne peux pas t même besoin d'un accès direct à des opérandes individuels. p> p>
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!