RulserParser: import os, seeing as how we use it

    Signed-off-by: Gregory M. Turner <gmt@be-evil.net>
RulesParser.NewLexer: object.__new__ thinko

Here I passed the *args, **kwargs along to my
invocation of object.__new__.  However, object.__new__
does not take a bunch of args.  Those arguments
are intended for the lexer instantiation and are
used there subsequently... in other words, they have
nothing to do with object.__new__.

Signed-off-by: Gregory M. Turner <gmt@be-evil.net>
RulesParser.NewParser: drop unused "names" dict

Whatever that variable is, it was some boilerplate I copy-pasted from
upstream examples.  Hope it doesn't serve any useful purpose! :)

But I can't seem to find any in the code, I have to imagine it's just
some kind of crufty nonsense with no utility.

Signed-off-by: Gregory M. Turner <gmt@be-evil.net>
RulesParser.RulesParser.parse: return results

It might be a nice touch if there were some way to get the parsed result,
seeing as how we went to all the work of generating it.
RulesParser.RulesParser: constructor argument enhancements

The RulesParser constructor code (largely cut-pasted from ply examples)
does a piss-poor job of respecting the passwd in kwargs.  Clearly, the
sane thing to do is to respect as many arguments as are applicable to
both the lexer and the parser.  To ensure that we do so, and to avoid
creating argument conflicts between kwargs and the hard-coded arguments,
we create a separate whitelist of non-special-cased arguments for lex.lex and
yacc.yacc invocations.

Signed-off-by: Gregory M. Turner <gmt@be-evil.net>
.gitignore: .swp

Signed-off-by: Gregory M. Turner <gmt@be-evil.net>
RulesParser.RulesParser: outermost parsing rules

Rewire the outermost parsing rules, a bit, to something that might
actually stand a chance of working out:

add an outermost "rulesprogram" production.  This may come in handy
later if there is need for some special constructs in the global
context, or, on the production side, if there is some final optimization
phase or other filtering that should be applied once the entire
parse-tree is finalized for a program (although these could also be
applied externally, given that "we are done parsing" and would otherwise
just return our result).

Change the "statements" production to use left-binding-friendly
grammar rule.

Move the semicolon slurping into the statement production.  This will
eventually turn into a disjunction of possible statement types, so
it will wind up looking like:

  '''statement : assignment SEMICOLON
               | conditional SEMICOLON
	       | functioncall SEMICOLON
	       .
	       .
	       .'''

If I ever want to support c-style context-dependant semicolon skipping,
I'll have to rethink this entirely, probably putting it back into
statements.

Signed-off-by: Gregory M. Turner <gmt@be-evil.net>
RulesParser.RulesParser: Parse string 'expressions'

nb: I've avoided the term "expression" since, there is only one
datatype in the rules language, thusfar, and therefore we can just call
them 'values' or 'strings'  Actually, I guess there is one other
class of expression-y construct: booleans.  But thus far, you can never
use one in place of the other; in any given context either a boolean
or a string is called for, and therefore there's no need to use such
abstract terminology as "type" or "expression" when talking about them.

Thankfully, since we have already doled out waaay more expressive power
than really was called for, mostly in the interest of creating an easily
grokked rule configuration syntax (how easy it is to actually write code
for it remains to be seen, but any experienced gentoo developer looking at
the rules files ought instantly be be able to grok 90% of their contents).

Aaanywho... whatever we want to call them, here I flesh out the
productions for right-hand-side strings, including back-quoted
characters, literal text, and psueod-bash-ish variable substitutions.

Signed-off-by: Gregory M. Turner <gmt@be-evil.net>
RulesParser.RulesParser: add p_error pseudoproduction

This is required to build the parser successfully.  The rule is
currently untested and probably has bugs.

With this patch we are now able to parse any valid chain of assignment
statements:

    >>> from OverlayUpstreamTracking.RulesParser import RulesParser
    >>> rp = RulesParser()
    WARNING: Token 'TILDEEQUALS' defined, but not used
    .
    .
    WARNING: There are 32 unused tokens
    >>> prog = '''x := "\\${foo} is \\"${foo}\\".";
    ... y := "${x}";'''
    >>> print prog
    x := "\${foo} is \"${foo}\".";
    y := "${x}";
    >>> print rp.parse(prog)
    ('RULESPROGRAM', ('ASSIGN', 'x', ('STRING', ('STRINGLITERAL', '$'),
    ('STRINGLITERAL', '{foo} is '), ('STRINGLITERAL', '"'),
    ('VARIABLE-SUBSTITUTION', 'foo'), ('STRINGLITERAL', '"'),
    ('STRINGLITERAL', '.'))), ('ASSIGN', 'y', ('STRING',
    ('VARIABLE-SUBSTITUTION', 'x'))))
    >>>

    Notice the contiguous STRINGLITERAL elements in the STRINGs -- that is
    pretty dumb, I plan to find some reasonable way to have these
    automagically merged into single STRINGLITERALs.