|
NAMEJE::Parser - Framework for customising JE's parserSYNOPSISuse JE; use JE::Parser; $je = new JE; $p = new JE::Parser $je; # or: $p = $je->new_parser $p->delete_statement('for', 'while', 'do'); # disable loops $p->add_statement(try => \&parser); # replace existing 'try' statement DESCRIPTIONThis allows one to change the list of statement types that the parser looks for. For instance, one could disable loops for a mini-JavaScript, or add extensions to the language, such as the 'catch-if' clause of a "try" statement.As yet, "delete_statement" works, but I've not finished designing the API for "add_statement". I might provide an API for extending expressions, if I can resolve the complications caused by the 'new' operator. If anyone else wants to have a go at it, be my guest. :-) METHODS
Maybe we need support for a JavaScript function to be called to handnle the statement.
EXPORTSNone by default. You may choose to export the following:Exported Variables... blah blah blah ...Exported FunctionsThese all have "()" for their prototype, except for "expected" which has "($)".... blah blah blah ... SYNTAX ERRORS(To be written)expected 'aaaa'; # will be changed to 'Expected aaaa but found....' die \\"You can't put a doodad after a frombiggle!"; # complete message die 'aoenstuhoeanthu'; # big no-no (the error is propagated) EXAMPLESMini JavaScriptThis is an example of a mini JavaScript that does not allow loops or the creation of functions.use JE; $j = new JE; $p = $j->new_parser; $p->delete_statement('for','while','do','-function'); Since function expressions could still create functions, we need to remove the Function prototype object. Someone might then try to put it back with "Function = parseInt.constructor", so we'll overwrite Function with an undeletable read-only undefined property. $j->prop({ name => 'Function', value => undef, readonly => 1, dontdel => 1 }); Then, after this, we call "$p->eval('...')" to run JS code. Perl-style for(LIST) loopWell, after writing this example, it seems to me this API is not sufficient....This example doesn't actually work yet. use JE; use JE::Parser qw'$s ident expr statement expected'; $j = new JE; $p = $j->new_parser; $p->add_statement('for-list', sub { /\Gfor$s/cog or return; my $loopvar = ident or return; /\G$s\($s/cog or return; my @expressions; do { # This line doesn't actually work properly because # 'expr' will gobble up all the commas @expressions == push @expressions, expr and return; # If nothing gets pushed on to the # list, we need to give the default # 'for' handler a chance, instead of # throwing an error. } while /\G$s,$s/cog; my $statement = statement or expected 'statement'; return bless { var => $loopvar, expressions => \@expressions, statement => $statement }, 'Local::JEx::ForList'; } ); package Local::JEx::ForList; sub eval { my $self = shift; local $JE::Code::scope = bless [@$JE::Code::scope], 'JE::Scope'; # I've got to come up with a better interface than this. my $obj = $JE::Code::global->eval('new Object'); push @$JE::Code::scope, $obj; for (@{$self->{expressions}}) { $obj->{ $self->{loopvar} } = $_->eval; $self->{statement}->execute; } } SEE ALSOJE and JE::Code.
Visit the GSP FreeBSD Man Page Interface. |