import unittest
import re
import textwrap
import antlr3
import testbase


# Left-recursion resolution is not yet enabled in the tool.

# class TestLeftRecursion(testbase.ANTLRTest):
#     def parserClass(self, base):
#         class TParser(base):
#             def __init__(self, *args, **kwargs):
#                 super().__init__(*args, **kwargs)

#                 self._output = ""


#             def capture(self, t):
#                 self._output += str(t)


#             def recover(self, input, re):
#                 # no error recovery yet, just crash!
#                 raise

#         return TParser


#     def execParser(self, grammar, grammarEntry, input):
#         lexerCls, parserCls = self.compileInlineGrammar(grammar)

#         cStream = antlr3.StringStream(input)
#         lexer = lexerCls(cStream)
#         tStream = antlr3.CommonTokenStream(lexer)
#         parser = parserCls(tStream)
#         getattr(parser, grammarEntry)()
#         return parser._output


#     def runTests(self, grammar, tests, grammarEntry):
#         lexerCls, parserCls = self.compileInlineGrammar(grammar)

#         build_ast = re.search(r'output\s*=\s*AST', grammar)

#         for input, expecting in tests:
#             cStream = antlr3.StringStream(input)
#             lexer = lexerCls(cStream)
#             tStream = antlr3.CommonTokenStream(lexer)
#             parser = parserCls(tStream)
#             r = getattr(parser, grammarEntry)()
#             found = parser._output
#             if build_ast:
#               found += r.tree.toStringTree()

#             self.assertEqual(
#                 expecting, found,
#                 "{!r} != {!r} (for input {!r})".format(expecting, found, input))


#     def testSimple(self):
#         grammar = textwrap.dedent(
#             r"""
#             grammar T;
#             options {
#                 language=Python3;
#             }
#             s : a { self.capture($a.text) } ;
#             a : a ID
#               | ID
#               ;
#             ID : 'a'..'z'+ ;
#             WS : (' '|'\n') {self.skip()} ;
#             """)

#         found = self.execParser(grammar, 's', 'a b c')
#         expecting = "abc"
#         self.assertEqual(expecting, found)


#     def testSemPred(self):
#         grammar = textwrap.dedent(
#             r"""
#             grammar T;
#             options {
#                 language=Python3;
#             }
#             s : a { self.capture($a.text) } ;
#             a : a {True}? ID
#               | ID
#               ;
#             ID : 'a'..'z'+ ;
#             WS : (' '|'\n') {self.skip()} ;
#             """)

#         found = self.execParser(grammar, "s", "a b c")
#         expecting = "abc"
#         self.assertEqual(expecting, found)

#     def testTernaryExpr(self):
#         grammar = textwrap.dedent(
#             r"""
#             grammar T;
#             options {
#                 language=Python3;
#                 output=AST;
#             }
#             e : e '*'^ e
#               | e '+'^ e
#               | e '?'<assoc=right>^ e ':'! e
#               | e '='<assoc=right>^ e
#               | ID
#               ;
#             ID : 'a'..'z'+ ;
#             WS : (' '|'\n') {self.skip()} ;
#             """)

#         tests = [
#             ("a", "a"),
#             ("a+b", "(+ a b)"),
#             ("a*b", "(* a b)"),
#             ("a?b:c", "(? a b c)"),
#             ("a=b=c", "(= a (= b c))"),
#             ("a?b+c:d", "(? a (+ b c) d)"),
#             ("a?b=c:d", "(? a (= b c) d)"),
#             ("a? b?c:d : e", "(? a (? b c d) e)"),
#             ("a?b: c?d:e", "(? a b (? c d e))"),
#             ]
#         self.runTests(grammar, tests, "e")


#     def testDeclarationsUsingASTOperators(self):
#         grammar = textwrap.dedent(
#             r"""
#             grammar T;
#             options {
#                 language=Python3;
#                 output=AST;
#             }
#             declarator
#                     : declarator '['^ e ']'!
#                     | declarator '['^ ']'!
#                     | declarator '('^ ')'!
#                     | '*'^ declarator // binds less tight than suffixes
#                     | '('! declarator ')'!
#                     | ID
#                     ;
#             e : INT ;
#             ID : 'a'..'z'+ ;
#             INT : '0'..'9'+ ;
#             WS : (' '|'\n') {self.skip()} ;
#             """)

#         tests = [
#             ("a", "a"),
#             ("*a", "(* a)"),
#             ("**a", "(* (* a))"),
#             ("a[3]", "([ a 3)"),
#             ("b[]", "([ b)"),
#             ("(a)", "a"),
#             ("a[]()", "(( ([ a))"),
#             ("a[][]", "([ ([ a))"),
#             ("*a[]", "(* ([ a))"),
#             ("(*a)[]", "([ (* a))"),
#             ]
#         self.runTests(grammar, tests, "declarator")


#     def testDeclarationsUsingRewriteOperators(self):
#         grammar = textwrap.dedent(
#             r"""
#             grammar T;
#             options {
#                 language=Python3;
#                 output=AST;
#             }
#             declarator
#                     : declarator '[' e ']' -> ^('[' declarator e)
#                     | declarator '[' ']' -> ^('[' declarator)
#                     | declarator '(' ')' -> ^('(' declarator)
#                     | '*' declarator -> ^('*' declarator)  // binds less tight than suffixes
#                     | '(' declarator ')' -> declarator
#                     | ID -> ID
#                     ;
#             e : INT ;
#             ID : 'a'..'z'+ ;
#             INT : '0'..'9'+ ;
#             WS : (' '|'\n') {self.skip()} ;
#             """)

#         tests = [
#             ("a", "a"),
#             ("*a", "(* a)"),
#             ("**a", "(* (* a))"),
#             ("a[3]", "([ a 3)"),
#             ("b[]", "([ b)"),
#             ("(a)", "a"),
#             ("a[]()", "(( ([ a))"),
#             ("a[][]", "([ ([ a))"),
#             ("*a[]", "(* ([ a))"),
#             ("(*a)[]", "([ (* a))"),
#             ]
#         self.runTests(grammar, tests, "declarator")


#     def testExpressionsUsingASTOperators(self):
#         grammar = textwrap.dedent(
#             r"""
#             grammar T;
#             options {
#                 language=Python3;
#                 output=AST;
#             }
#             e : e '.'^ ID
#               | e '.'^ 'this'
#               | '-'^ e
#               | e '*'^ e
#               | e ('+'^|'-'^) e
#               | INT
#               | ID
#               ;
#             ID : 'a'..'z'+ ;
#             INT : '0'..'9'+ ;
#             WS : (' '|'\n') {self.skip()} ;
#             """)

#         tests = [
#             ("a", "a"),
#             ("1", "1"),
#             ("a+1", "(+ a 1)"),
#             ("a*1", "(* a 1)"),
#             ("a.b", "(. a b)"),
#             ("a.this", "(. a this)"),
#             ("a-b+c", "(+ (- a b) c)"),
#             ("a+b*c", "(+ a (* b c))"),
#             ("a.b+1", "(+ (. a b) 1)"),
#             ("-a", "(- a)"),
#             ("-a+b", "(+ (- a) b)"),
#             ("-a.b", "(- (. a b))"),
#             ]
#         self.runTests(grammar, tests, "e")


#     @testbase.broken(
#         "Grammar compilation returns errors", testbase.GrammarCompileError)
#     def testExpressionsUsingRewriteOperators(self):
#         grammar = textwrap.dedent(
#             r"""
#             grammar T;
#             options {
#                 language=Python3;
#                 output=AST;
#             }
#             e : e '.' ID                   -> ^('.' e ID)
#               | e '.' 'this'               -> ^('.' e 'this')
#               | '-' e                      -> ^('-' e)
#               | e '*' b=e                  -> ^('*' e $b)
#               | e (op='+'|op='-') b=e      -> ^($op e $b)
#               | INT                        -> INT
#               | ID                         -> ID
#               ;
#             ID : 'a'..'z'+ ;
#             INT : '0'..'9'+ ;
#             WS : (' '|'\n') {self.skip()} ;
#             """)

#         tests = [
#             ("a", "a"),
#             ("1", "1"),
#             ("a+1", "(+ a 1)"),
#             ("a*1", "(* a 1)"),
#             ("a.b", "(. a b)"),
#             ("a.this", "(. a this)"),
#             ("a+b*c", "(+ a (* b c))"),
#             ("a.b+1", "(+ (. a b) 1)"),
#             ("-a", "(- a)"),
#             ("-a+b", "(+ (- a) b)"),
#             ("-a.b", "(- (. a b))"),
#             ]
#         self.runTests(grammar, tests, "e")


#     def testExpressionAssociativity(self):
#         grammar = textwrap.dedent(
#             r"""
#             grammar T;
#             options {
#                 language=Python3;
#                 output=AST;
#             }
#             e
#               : e '.'^ ID
#               | '-'^ e
#               | e '^'<assoc=right>^ e
#               | e '*'^ e
#               | e ('+'^|'-'^) e
#               | e ('='<assoc=right>^ |'+='<assoc=right>^) e
#               | INT
#               | ID
#               ;
#             ID : 'a'..'z'+ ;
#             INT : '0'..'9'+ ;
#             WS : (' '|'\n') {self.skip()} ;
#             """)

#         tests = [
#             ("a", "a"),
#             ("1", "1"),
#             ("a+1", "(+ a 1)"),
#             ("a*1", "(* a 1)"),
#             ("a.b", "(. a b)"),
#             ("a-b+c", "(+ (- a b) c)"),
#             ("a+b*c", "(+ a (* b c))"),
#             ("a.b+1", "(+ (. a b) 1)"),
#             ("-a", "(- a)"),
#             ("-a+b", "(+ (- a) b)"),
#             ("-a.b", "(- (. a b))"),
#             ("a^b^c", "(^ a (^ b c))"),
#             ("a=b=c", "(= a (= b c))"),
#             ("a=b=c+d.e", "(= a (= b (+ c (. d e))))"),
#             ]
#         self.runTests(grammar, tests, "e")


#     def testJavaExpressions(self):
#       grammar = textwrap.dedent(
#             r"""
#             grammar T;
#             options {
#                 language=Python3;
#                 output=AST;
#             }
#             expressionList
#                 :   e (','! e)*
#                 ;
#             e   :   '('! e ')'!
#                 |   'this'
#                 |   'super'
#                 |   INT
#                 |   ID
#                 |   type '.'^ 'class'
#                 |   e '.'^ ID
#                 |   e '.'^ 'this'
#                 |   e '.'^ 'super' '('^ expressionList? ')'!
#                 |   e '.'^ 'new'^ ID '('! expressionList? ')'!
#                 |       'new'^ type ( '(' expressionList? ')'! | (options {k=1;}:'[' e ']'!)+) // ugly; simplified
#                 |   e '['^ e ']'!
#                 |   '('^ type ')'! e
#                 |   e ('++'^ | '--'^)
#                 |   e '('^ expressionList? ')'!
#                 |   ('+'^|'-'^|'++'^|'--'^) e
#                 |   ('~'^|'!'^) e
#                 |   e ('*'^|'/'^|'%'^) e
#                 |   e ('+'^|'-'^) e
#                 |   e ('<'^ '<' | '>'^ '>' '>' | '>'^ '>') e
#                 |   e ('<='^ | '>='^ | '>'^ | '<'^) e
#                 |   e 'instanceof'^ e
#                 |   e ('=='^ | '!='^) e
#                 |   e '&'^ e
#                 |   e '^'<assoc=right>^ e
#                 |   e '|'^ e
#                 |   e '&&'^ e
#                 |   e '||'^ e
#                 |   e '?' e ':' e
#                 |   e ('='<assoc=right>^
#                       |'+='<assoc=right>^
#                       |'-='<assoc=right>^
#                       |'*='<assoc=right>^
#                       |'/='<assoc=right>^
#                       |'&='<assoc=right>^
#                       |'|='<assoc=right>^
#                       |'^='<assoc=right>^
#                       |'>>='<assoc=right>^
#                       |'>>>='<assoc=right>^
#                       |'<<='<assoc=right>^
#                       |'%='<assoc=right>^) e
#                 ;
#             type: ID
#                 | ID '['^ ']'!
#                 | 'int'
#                 | 'int' '['^ ']'!
#                 ;
#             ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;
#             INT : '0'..'9'+ ;
#             WS : (' '|'\n') {self.skip()} ;
#             """)

#       tests = [
#           ("a", "a"),
#           ("1", "1"),
#           ("a+1", "(+ a 1)"),
#           ("a*1", "(* a 1)"),
#           ("a.b", "(. a b)"),
#           ("a-b+c", "(+ (- a b) c)"),
#           ("a+b*c", "(+ a (* b c))"),
#           ("a.b+1", "(+ (. a b) 1)"),
#           ("-a", "(- a)"),
#           ("-a+b", "(+ (- a) b)"),
#           ("-a.b", "(- (. a b))"),
#           ("a^b^c", "(^ a (^ b c))"),
#           ("a=b=c", "(= a (= b c))"),
#           ("a=b=c+d.e", "(= a (= b (+ c (. d e))))"),
#           ("a|b&c", "(| a (& b c))"),
#           ("(a|b)&c", "(& (| a b) c)"),
#           ("a > b", "(> a b)"),
#           ("a >> b", "(> a b)"),  # text is from one token
#           ("a < b", "(< a b)"),
#           ("(T)x", "(( T x)"),
#           ("new A().b", "(. (new A () b)"),
#           ("(T)t.f()", "(( (( T (. t f)))"),
#           ("a.f(x)==T.c", "(== (( (. a f) x) (. T c))"),
#           ("a.f().g(x,1)", "(( (. (( (. a f)) g) x 1)"),
#           ("new T[((n-1) * x) + 1]", "(new T [ (+ (* (- n 1) x) 1))"),
#           ]
#       self.runTests(grammar, tests, "e")


#     def testReturnValueAndActions(self):
#         grammar = textwrap.dedent(
#             r"""
#             grammar T;
#             options {
#                 language=Python3;
#             }
#             s : e { self.capture($e.v) } ;
#             e returns [v, ignored]
#               : e '*' b=e {$v *= $b.v;}
#               | e '+' b=e {$v += $b.v;}
#               | INT {$v = int($INT.text);}
#               ;
#             INT : '0'..'9'+ ;
#             WS : (' '|'\n') {self.skip()} ;
#             """)

#         tests = [
#             ("4", "4"),
#             ("1+2", "3")
#             ]
#         self.runTests(grammar, tests, "s")


#     def testReturnValueAndActionsAndASTs(self):
#         grammar = textwrap.dedent(
#             r"""
#             grammar T;
#             options {
#                 language=Python3;
#                 output=AST;
#             }
#             s : e { self.capture("v={}, ".format($e.v)) } ;
#             e returns [v, ignored]
#               : e '*'^ b=e {$v *= $b.v;}
#               | e '+'^ b=e {$v += $b.v;}
#               | INT {$v = int($INT.text);}
#               ;
#             INT : '0'..'9'+ ;
#             WS : (' '|'\n') {self.skip()} ;
#             """)

#         tests = [
#             ("4", "v=4, 4"),
#             ("1+2", "v=3, (+ 1 2)"),
#             ]
#         self.runTests(grammar, tests, "s")


if __name__ == '__main__':
    unittest.main()