#!/usr/bin/env python
# -*- coding: utf-8 -*-

# CAVEAT UTILITOR
#
# This file was automatically generated by Grako.
#
#    https://pypi.python.org/pypi/grako/
#
# Any changes you make to it will be overwritten the next time
# the file is generated.


from __future__ import (print_function, division, absolute_import,
                        unicode_literals)

from grako.parsing import graken, Parser
from grako.util import re, RE_FLAGS  # noqa


__version__ = (2016, 2, 17, 20, 35, 22, 2)

__all__ = [
    'DisplayPatternParser',
    'DisplayPatternSemantics',
    'main'
]


class DisplayPatternParser(Parser):
    def __init__(self,
                 whitespace=None,
                 nameguard=None,
                 comments_re=None,
                 eol_comments_re=None,
                 ignorecase=None,
                 left_recursion=True,
                 **kwargs):
        super(DisplayPatternParser, self).__init__(
            whitespace=whitespace,
            nameguard=nameguard,
            comments_re=comments_re,
            eol_comments_re=eol_comments_re,
            ignorecase=ignorecase,
            left_recursion=left_recursion,
            **kwargs
        )

    @graken()
    def _start_(self):
        self._pattern_()
        self._check_eof()

    @graken()
    def _pattern_(self):

        def block0():
            with self._choice():
                with self._option():
                    self._text_()
                with self._option():
                    self._tag_()
                with self._option():
                    self._function_()
                self._error('no available options')
        self._closure(block0)

    @graken()
    def _tag_(self):
        with self._group():
            self._token('%')
            self._string_()
            self.ast['name'] = self.last_node

            def block2():
                self._token(',')
                with self._group():
                    self._parameter_()
                self.ast.setlist('parameters', self.last_node)
            self._closure(block2)
            self._token('%')
        self.ast['tag'] = self.last_node

        self.ast._define(
            ['tag', 'name'],
            ['parameters']
        )

    @graken()
    def _function_(self):
        with self._group():
            self._token('$')
            self._string_()
            self.ast['name'] = self.last_node
            self._token('(')
            with self._optional():
                with self._group():
                    self._parameter_()
                self.ast.setlist('parameters', self.last_node)

                def block3():
                    self._token(',')
                    with self._group():
                        self._parameter_()
                    self.ast.setlist('parameters', self.last_node)
                self._closure(block3)
            self._token(')')
        self.ast['function'] = self.last_node

        self.ast._define(
            ['function', 'name'],
            ['parameters']
        )

    @graken()
    def _parameter_(self):
        with self._optional():

            def block0():
                self._token(' ')
            self._closure(block0)
            self._string_()
            self.ast['name'] = self.last_node
            self._token('=')
        with self._optional():
            self._pattern_()
            self.ast['value'] = self.last_node

        self.ast._define(
            ['name', 'value'],
            []
        )

    @graken()
    def _text_(self):
        self._pattern(r'(\\\\|\\%|\\\$|\\,|\\\(|\\\)|\\=|\\n|\\t|[^\\%$,()])+')
        self.ast['text'] = self.last_node

        self.ast._define(
            ['text'],
            []
        )

    @graken()
    def _string_(self):
        self._pattern(r'([^\\%$,()=])+')


class DisplayPatternSemantics(object):
    def start(self, ast):
        return ast

    def pattern(self, ast):
        return ast

    def tag(self, ast):
        return ast

    def function(self, ast):
        return ast

    def parameter(self, ast):
        return ast

    def text(self, ast):
        return ast

    def string(self, ast):
        return ast


def main(filename, startrule, trace=False, whitespace=None, nameguard=None):
    import json
    with open(filename) as f:
        text = f.read()
    parser = DisplayPatternParser(parseinfo=False)
    ast = parser.parse(
        text,
        startrule,
        filename=filename,
        trace=trace,
        whitespace=whitespace,
        nameguard=nameguard)
    print('AST:')
    print(ast)
    print()
    print('JSON:')
    print(json.dumps(ast, indent=2))
    print()


if __name__ == '__main__':
    import argparse
    import string
    import sys

    class ListRules(argparse.Action):
        def __call__(self, parser, namespace, values, option_string):
            print('Rules:')
            for r in DisplayPatternParser.rule_list():
                print(r)
            print()
            sys.exit(0)

    parser = argparse.ArgumentParser(
                        description="Simple parser for DisplayPattern.")
    parser.add_argument('-l', '--list', action=ListRules, nargs=0,
                        help="list all rules and exit")
    parser.add_argument('-n', '--no-nameguard', action='store_true',
                        dest='no_nameguard',
                        help="disable the 'nameguard' feature")
    parser.add_argument('-t', '--trace', action='store_true',
                        help="output trace information")
    parser.add_argument('-w', '--whitespace', type=str,
                        default=string.whitespace,
                        help="whitespace specification")
    parser.add_argument('file', metavar="FILE", help="the input file to parse")
    parser.add_argument('startrule', metavar="STARTRULE",
                        help="the start rule for parsing")
    args = parser.parse_args()

    main(
        args.file,
        args.startrule,
        trace=args.trace,
        whitespace=args.whitespace,
        nameguard=not args.no_nameguard
    )
