Tài liệu PHP Objects, Patterns and Practice- P11 - Pdf 87

APPENDIX B ■ A SIMPLE PARSER
479
}

function trigger( Scanner $scanner ) {
return true;
}

protected function doScan( Scanner $scanner ) {
$start_state = $scanner->getState();
if ( empty( $this->parsers ) ) {
return true;
}
$parser = $this->parsers[0];
$count = 0;

while ( true ) {
if ( $this->max > 0 && $count >= $this->max ) {
return true;
}

if ( ! $parser->trigger( $scanner ) ) {
if ( $this->min == 0 || $count >= $this->min ) {
return true;
} else {
$scanner->setState( $start_state );
return false;
}
}
if ( ! $parser->scan( $scanner ) ) {
if ( $this->min == 0 || $count >= $this->min ) {

$start_state = $scanner->getState();
if ( $type == $parser->trigger( $scanner ) &&
$parser->scan( $scanner ) ) {
return true;
}
}
$scanner->setState( $start_state );
return false;
}
}

// this terminal parser matches a string literal
class StringLiteralParse extends Parser {

function trigger( Scanner $scanner ) {
return ( $scanner->tokenType() == Scanner::APOS ||
$scanner->tokenType() == Scanner::QUOTE );
}

protected function push( Scanner $scanner ) {
return;
}

protected function doScan( Scanner $scanner ) {
$quotechar = $scanner->tokenType();
$ret = false;
$string = "";
while ( $token = $scanner->nextToken() ) {
if ( $token == $quotechar ) {
$ret = true;

}
return ( $this->word == $scanner->token() );
}

protected function doScan( Scanner $scanner ) {
$ret = ( $this->trigger( $scanner ) );
return $ret;
}
}
By combining terminal and nonterminal Parser objects, I can build a reasonably sophisticated
parser. You can see all the Parser classes I use for this example in Figure B–1.

Figure B–1.

The Parser classes
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
APPENDIX B ■ A SIMPLE PARSER
482
The idea behind this use of the Composite pattern is that a client can build up a grammar in code
that closely matches EBNF notation. Table B–1 shows the parallels between these classes and EBNF
fragments.
Table B–1.

Composite Parsers and EBNF
Class EBNF Example Description
AlternationParse orExpr | andExpr
Either one or another
SequenceParse 'and' operand
A list (all required in order)
RepetitionParse ( eqExpr )*

}

function compile( $statement_str ) {
// build parse tree
$context = new \gi\parse\Context();
$scanner = new \gi\parse\Scanner(
new \gi\parse\StringReader($statement_str), $context );
$statement = $this->expression();
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
APPENDIX B ■ A SIMPLE PARSER
483
$scanresult = $statement->scan( $scanner );

if ( ! $scanresult || $scanner->tokenType() != \gi\parse\Scanner::EOF ) {
$msg = "";
$msg .= " line: {$scanner->line_no()} ";
$msg .= " char: {$scanner->char_no()}";
$msg .= " token: {$scanner->token()}\n";
throw new Exception( $msg );
}

$this->interpreter = $scanner->getContext()->popResult();
}

function expression() {
if ( ! isset( $this->expression ) ) {
$this->expression = new \gi\parse\SequenceParse();
$this->expression->add( $this->operand() );
$bools = new \gi\parse\RepetitionParse( );
$whichbool = new \gi\parse\AlternationParse();

$exp->add( $this->expression() );
$exp->add( new \gi\parse\CharacterParse( ')' ))->discard();
$comp->add( $exp );
$comp->add( new \gi\parse\StringLiteralParse() )
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
APPENDIX B ■ A SIMPLE PARSER
484
->setHandler( new StringLiteralHandler() );
$comp->add( $this->variable() );
$this->operand->add( $comp );
$this->operand->add( new \gi\parse\RepetitionParse( ) )
->add($this->eqExpr());
}
return $this->operand;
}

function eqExpr() {
$equals = new \gi\parse\SequenceParse();
$equals->add( new \gi\parse\WordParse('equals') )->discard();
$equals->add( $this->operand() );
$equals->setHandler( new EqualsHandler() );
return $equals;
}

function variable() {
$variable = new \gi\parse\SequenceParse();
$variable->add( new \gi\parse\CharacterParse( '$' ))->discard();
$variable->add( new \gi\parse\WordParse());
$variable->setHandler( new VariableHandler() );
return $variable;

485
object. If the raw code does not parse, the compile() method throws an exception. Otherwise, it retrieves
the result of compilation as left on the Scanner object’s Context. As you will see shortly, this should be an
Expression object. This result is stored in a property called $interpreter.
The evaluate() method makes a value available to the Expression tree. It does this by predefining a
VariableExpression object named input and registering it with the Context object that is then passed to
the main Expression object. As with variables such as $_REQUEST in PHP, this $input variable is always
available to MarkLogic coders.

Note See Chapter 11 for more about the
VariableExpression
class that is part of the Interpreter pattern
example.
The evaluate() method calls the Expression::interpret() method to generate a final result.
Remember, you need to retrieve interpreter results from the Context object.
So far, you have seen how to parse text and how to build a grammar. You also saw in Chapter 11 how
to use the Interpreter pattern to combine Expression objects and process a query. You have not yet seen,
though, how to relate the two processes. How do you get from a parse tree to the interpreter? The answer
lies in the Handler objects that can be associated with Parser objects using Parser::setHandler(). Let’s
take a look at the way to manage variables. I associate a VariableHandler with the Parser in the
variable() method:
$variable->setHandler( new VariableHandler() );
Here is the Handler interface:
namespace gi\parse;

interface Handler {
function handleMatch( Parser $parser,
Scanner $scanner );
}
And here is VariableHandler:

class BooleanOrHandler implements \gi\parse\Handler {
function handleMatch( \gi\parse\Parser $parser, \gi\parse\Scanner $scanner ) {
$comp1 = $scanner->getContext()->popResult();
$comp2 = $scanner->getContext()->popResult();
$scanner->getContext()->pushResult(
new BooleanOrExpression( $comp1, $comp2 ) );
}
}

class BooleanAndHandler implements \gi\parse\Handler {
function handleMatch( \gi\parse\Parser $parser, \gi\parse\Scanner $scanner ) {
$comp1 = $scanner->getContext()->popResult();
$comp2 = $scanner->getContext()->popResult();
$scanner->getContext()->pushResult(
new BooleanAndExpression( $comp1, $comp2 ) );
}
}
Bearing in mind that you also need the Interpreter example from Chapter 11 at hand, you can work
with the MarkParse class like this:
$input = 'five';
$statement = "( \$input equals 'five')";

$engine = new MarkParse( $statement );
$result = $engine->evaluate( $input );
print "input: $input evaluating: $statement\n";
if ( $result ) {
print "true!\n";
} else {
print "false!\n";
}

interface, class diagram, 158
make(), creating, 161
overview of, 157
abstract keyword, 45
abstract methods, 102
accept(), 211–212
acceptance tests, 379
AccessManager class, 217–218
acquire(), 333
add command, 371–372
add(), 282–283, 290, 478
addChargeableItem(), 48
addClassroot(), 250
addClean(), 293
addDirty(), 293
addEmployee(), 147
addNew(), 293, 295
addObserver(), 333
addParam(), 102
AddSpace command, 245, 247
addTest(), 304
addToMap(), 291, 300
addUnit(), 171, 173, 176, 213
addUser(), 381, 385
AddVenue command, 245, 247, 251, 255
addVenue(), 268
AddVenueController class
associated view, 260
code listing, 259
AddVenueTest class, code listing, 397

getView(), 253
implementing, 246
overview of, 245
parsing the configuration file, 249
setting configuration directives, code
listing, 247
status element, 249
statuses(), 255
storing the configuration data, 249
using an application controller to acquire
commands and views, illustration of,
254
view element, 248
application scope, 229
ApplicationHelper class, 225, 238–239, 244
code listing, 237
ApplicationRegistry class, 234, 238–239, 245
code listing, 232
ApptEncoder class, 153
Archer class, 170
argData(), 93
Army class, 171
ArmyVisitor class, 213–214
array hinting, 27
array_slice(), 91
artifacts, definition of, 449
artifactspublisher element, 449
as element, 341
assertEquals(), 384
assertions

branching, 459
Bugzilla, downloading and using, 460
build reports, 436
build target, 447
build.xml, 407, 409, 440
buildStatement(), 309
buildWhere(), 310
business logic layer, 223
Domain Model pattern, 269
getting on with the business of an
application, 264
Transaction Script pattern, 265
See also presentation layer
■ C
__call(), 60, 86
call_user_func(), 67, 86
call_user_func_array(), 86–87
callbacks, 66
catch clause, 54, 56
cc.pid, 439
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
■ INDEX
489
channel element, 335, 339
channel-discover command, 328
channel-info command, 328
char_no(), 473
CharacterParse class, code listing, 477
Chargeable interface, 47
checkout command, 374

ProcessRequest class, 180, 183
Prototype pattern, code listing, 163
removeUnit(), 173, 176
setDepth(), 211
splitting composite classes off into a
CompositeUnit class, 175
storage in relational databases, 178
storage in XML, 178
StructureRequest class, 180
summary of, 178
TaxCollectionVisitor class, 215
Tile class, 179
$tile property, 182
TileDecorator class, 182
Unit class, 170, 210
$units property, 171, 173
visit(), 212
visitArmy(), 213
class diagrams, 110
classData(), 90
classes
abstract classes, 45–46
abstract super class, creating, 142
accessing a class residing in a global (non-
namespaced) space, 75
accessing methods and properties in the
context of a class, 41
accessing property variables, 18
accessor methods, 37
array hinting, 27

function keyword, 19
get_class(), 83
get_class_methods(), 84
get_class_vars(), 85
get_declared_classes(), 82
get_parent_class(), 85
inheritance tree, building, 31
inheritance, definition of, 27
instanceof operator, 31, 83
invoking the parent class’s constructor, 32
is_callable(), 84
is_subclass_of(), 85
leaving an overzealous class unchanged,
109
locking down access control, 37
member variable, 17
method_exists(), 84
methods, definition of, 19
minimizing the use of concrete subclasses,
457
new operator, 16
null default values in hinted arguments, 27
organizing into package-like structures, 71
overridden method, invoking, 35
parent and child classes, 27
parent keyword, 33, 35
polymorphism, definition of, 106
prepending package names to class names,
72
private keyword, 17

CodeSniffer, 444
cohesion, definition of, 104
collection(), 294
CollectionParse class, code listing, 477
command and control layer, 223
Command class, 241, 247
code listing, 254
command element, 248
Command pattern
AccessManager class, 217–218
class diagram, 220
client, invoker, and receiver, 216
Command class, code listing, 217
execute(), 216
FeedbackCommand class, 219
implementing, 216
LoginCommand class, 217
overview of, 216
process(), 219
Registry class, 218
when application logic creeps into
command classes, 218
CommandContext class, code listing, 217
CommandFactory class, code listing, 218
CommandResolver class, 244
code listing, 240
CommsManager class, 153
code listing, 159
redesignating as an abstract class, 155
compile(), 484

SimpleXml extension, 52
Conf(), 55
ConfException class, 55
Config class, 330
Config_Container class, 330
Config.php, 330
config.xml, 436, 440, 443
config-get command, 324
lack of Pyrus support for, 325
config-show command, 324
configuration flags, hard-coding, 166
connect(), 138
const keyword, 44
constant properties
defining within a class, 44
naming conventions, 44
constraints, 111, 386
constructors
__construct(), 21
inheritance and, 33
naming convention, 21
contents element, 336
Context class, code listing, 472
Continuous Integration (CI), 7, 322, 460
adding a version control system, 429
adding UserTests as a test suite class, 430
applying coding standards to a project, 433
automating the build and test process, 428
building and deploying a package using
package.xml, 435

ControllerMap class, code listing, 249
copy command, 373
copy element, table of attributes, 422
Copy task, 420, 422
@copyright tag, 352
coupling, 104
getNotifier(), 140
hiding the implementation details of a
notifier, 139
loosening, 139
MailNotifier class, 140
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
■ INDEX
492
Notifier class, 140
RegistrationMgr class, 140
TextNotifier class, 140
See also decoupling
create command, 363
create_function(), 67–68
createObject(), 278, 282, 287, 291, 298–300
CruiseControl
acquiring and building the userthing
project, 440
adding an install-package target, 447
adding your own build targets, 447
always element, 447
amending the CruiseControl environment
to support phpUnderControl, 439
Ant, 436, 440

phpuc project command, using, 441
phpunit task, code example, 443
publishers element, 446, 449
receiving failure notifications, 446
setting up a basic report for the install-
package target, 449
target elements, 443
testing the Validate class, 445
Tests tab, 446
ThoughtWorks, 436
usessl element, 447
validateUser(), 446
viewing an error report for a failed test, 446
wrong element, 448
XML Log File link, 449
CVS, 459
■ D
data layer, 223, 275
Data Mapper pattern
add(), 282–283
advantages and disadvantages of, 287
createObject(), 278, 282, 287
data mapper, definition of, 276
deconstructing into a set of finer-grained
patterns, 298
decoupling between the Domain layer and
database, 288
disconnect between classes and relational
databases, 276
doCreateObject(), 278–279, 286–287

object-relational impedance mismatch, 276
persistence classes, illustration of, 312
print_r(), 279
Registry class, 278
selectAllStmt(), 286
selectStmt(), 279, 286
setSpaces(), 285, 287
targetClass(), 283
update(), 279
using HelperFactory to acquire both
collections and mappers, 284
Venue class, code listing, 284
VenueCollection class, 282
VenueCollection interface, code listing, 283
VenueMapper class, code listing, 278
Data Source Name (DSN), 138
data types
checking the type of a variable, 23
class type hints, 26
PHP as a loosely typed language, 22
primitive types and test functions, table of,
22
strategies for dealing with argument types,
25
type-related errors, preventing, 25
DBFace class, 404
DecorateProcess class, 183
Decorator pattern
class diagram, 182
inheritance tree, class diagram, 180

definition of, 6, 123, 455
developing a vocabulary for describing
problems and solutions, 456
early concept of, 4
favoring composition over inheritance, 169
Fowler, Martin, 124–125, 143, 456
Gamma, Erich, 125
Gang of Four’s categorization of, 143
Gang of Four’s format for structuring
patterns, 126
half-baked nature of, 456
Helm, Richard, 125
implementing nuanced solutions, 126
inscribing approaches to particular
problems, 124
Johnson, Ralph, 125
language independence of, 127
naming, 125
overuse of, 456
overview of, 125
pattern languages, 125
patterns suggest complementary patterns,
456
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.


Nhờ tải bản gốc

Tài liệu, ebook tham khảo khác

Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status