Plug memory leak with PhutilErrorTrap

Summary:
Since PhutilErrorTrap registers itself with PhutilErrorHandler, it still has a positive refcount after `unset()` and is not destroyed. Destroy it explicitly.

(I didn't test this well in the original revision. :/)

Test Plan: Ran `phd debug phabricatorbot <config> -- --trace-memory` and saw climbing memory usage before this patch. After this patch, saw steady usage.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran, staticshock

Differential Revision: https://secure.phabricator.com/D6788
Provide access to CWD and Env for passthru by making it a class

Summary:
Ref T3733. Currently, `phutil_passthru()` can't take Env or CWD parameters. In T3733, it would be cleanest to be able to provide a CWD. (A similar thing came up recently with Env, although we solved that in a different way.)

This just moves `phutil_passthru()` into a class so we can specify more stuff without some sort of hacky signature.

I added a trivial "this code doesn't have any syntax errors" sort of unit test; doing more is difficult (I think we'd have to execute a wrapper subprocess and have that subprocess do the actual passthru).

Test Plan: Ran unit tests; created this revision on the new code using `arc`, which hits `phutil_passthru()` to invoke EDITOR.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T3733

Differential Revision: https://secure.phabricator.com/D6774
Fix Phage unit test issue with ErrorTrap

Summary: The Phage agent build became dependent on PhutilErrorTrap after its introduction. Rather than build it into the agent, make the dependency soft. Also make the ServiceProfiler dependency soft to limit the surface area of the agent.

Test Plan: `arc unit --everything`

Reviewers: btrahan, wez, michael.plusnin

Reviewed By: wez

CC: aran

Differential Revision: https://secure.phabricator.com/D6792
Add an LR(1) parser generator to libphutil

Summary:
This is a rehash of D4301, but broadly I want to use the little Conduit grammar we have to actually enforce types, e.g. `int`, `map<string, int>`, etc.

This grammar ended up being more complex than I was able to handle with a hand-rolled recursive-descent parser, so I implemented an LR(1) parser generator a while ago. It seems to work properly, it's just kind of silly to do this in PHP.

I think this isn't that terrible, though, and we can kind of see if we go anywhere with it, and replace it with some simpler recursive-descent thing or something if it stops making any sense or is a terrible idea.

Test Plan: Ran unit tests, built a little type library on top of this (next revision).

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2039

Differential Revision: https://secure.phabricator.com/D6794
Implement a simple type language

Summary:
Depends on D6794. Ref T2039. This implements a simple type language so we can typecheck things (like Conduit method calls) easily. For T2039, I want to typecheck a JSON file without writing a zillion lines of custom parser code.

I codegenerated the parser since it takes around 125ms to build.

Test Plan: Ran unit tests.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2039

Differential Revision: https://secure.phabricator.com/D6795