diff --git a/phply/phpparse.py b/phply/phpparse.py
index 69d012e..12dc62b 100644
--- a/phply/phpparse.py
+++ b/phply/phpparse.py
@@ -1569,8 +1569,17 @@ def p_encaps_list_string(p):
     if p[1] == '':
         p[0] = process_php_string_escapes(p[2])
     else:
-        p[0] = ast.BinaryOp('.', p[1], process_php_string_escapes(p[2]),
-                            lineno=p.lineno(2))
+        if isinstance(p[1], string_type):
+            # if it's only a string so far, just append the contents
+            p[0] = p[1] + process_php_string_escapes(p[2])
+        elif isinstance(p[1], ast.BinaryOp) and isinstance(p[1].right, string_type):
+            # if the last right leaf is a string, extend previous binop
+            p[0] = ast.BinaryOp('.', p[1].left, p[1].right + process_php_string_escapes(p[2]),
+                                lineno=p[1].lineno)
+        else:
+            # worst case - insert a binaryop
+            p[0] = ast.BinaryOp('.', p[1], process_php_string_escapes(p[2]),
+                                lineno=p.lineno(2))
 
 def p_encaps_var(p):
     'encaps_var : VARIABLE'

Issue with parsing HERE_DOC syntax
I've got a PHP file that has a big heredoc block in it. When I attempt to parse it, I get a recursion limit error: 

``` 
Traceback (most recent call last):
  File "php2json.py", line 31, in <module>
    output, indent=2)
  File "/Library/Python/2.7/site-packages/simplejson/__init__.py", line 276, in dump
    for chunk in iterable:
  File "/Library/Python/2.7/site-packages/simplejson/encoder.py", line 665, in _iterencode
    for chunk in _iterencode_list(o, _current_indent_level):
  File "/Library/Python/2.7/site-packages/simplejson/encoder.py", line 515, in _iterencode_list
    for chunk in chunks:
  File "/Library/Python/2.7/site-packages/simplejson/encoder.py", line 515, in _iterencode_list
    for chunk in chunks:
  File "/Library/Python/2.7/site-packages/simplejson/encoder.py", line 634, in _iterencode_dict
    for chunk in chunks:
  File "/Library/Python/2.7/site-packages/simplejson/encoder.py", line 515, in _iterencode_list
    for chunk in chunks:
  File "/Library/Python/2.7/site-packages/simplejson/encoder.py", line 515, in _iterencode_list
    for chunk in chunks:
  File "/Library/Python/2.7/site-packages/simplejson/encoder.py", line 634, in _iterencode_dict
    for chunk in chunks:
  File "/Library/Python/2.7/site-packages/simplejson/encoder.py", line 515, in _iterencode_list
    for chunk in chunks:
  File "/Library/Python/2.7/site-packages/simplejson/encoder.py", line 515, in _iterencode_list
    for chunk in chunks:
  File "/Library/Python/2.7/site-packages/simplejson/encoder.py", line 634, in _iterencode_dict
    for chunk in chunks:
```

And it goes on like that for hundreds or thousands of lines. I'm not sure what structure the data was parsed into, but it appears to be a loop of some sort. 
diff --git a/tests/test_parser.py b/tests/test_parser.py
index 0ecb9a8..62bf2cc 100644
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -235,18 +235,12 @@ EOT;
                        BinaryOp('.',
                                 BinaryOp('.',
                                          BinaryOp('.',
-                                                  BinaryOp('.',
-                                                           BinaryOp('.',
-                                                                    BinaryOp('.',
-                                                                             'This',
-                                                                             ' is a "'),
-                                                                    Variable('$heredoc')),
-                                                           '" with some '),
-                                                  ObjectProperty(Variable('$embedded'),
-                                                                 'variables')),
-                                         '.\n'),
-                                'This'),
-                       ' is not the EOT; this is:')]),
+                                                  'This is a "',
+                                                  Variable('$heredoc')),
+                                         '" with some '),
+                                ObjectProperty(Variable('$embedded'),
+                                               'variables')),
+                       '.\nThis is not the EOT; this is:')]),
     ]
     eq_ast(input, expected)
     if sys.version_info[0] < 3:

pip install -e .
parse_log_pytest
nose pytest
apt-get update apt-get install -y gcc
3.6
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
certifi==2021.5.30
importlib-metadata==4.8.3
iniconfig==1.1.1
nose==1.3.7
packaging==21.3
-e git+https://github.com/viraptor/phply.git@4a21aa038611ab6ebd0bf8ea5d3ee97e624339d3#egg=phply
pluggy==1.0.0
ply==3.11
py==1.11.0
pyparsing==3.1.4
pytest==7.0.1
tomli==1.2.3
typing_extensions==4.1.1
zipp==3.6.0

name: phply
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - nose==1.3.7
      - packaging==21.3
      - pluggy==1.0.0
      - ply==3.11
      - py==1.11.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - zipp==3.6.0
prefix: /opt/conda/envs/phply

tests/test_parser.py::test_heredoc
tests/test_parser.py::test_inline_html tests/test_parser.py::test_echo tests/test_parser.py::test_open_tag_with_echo tests/test_parser.py::test_exit tests/test_parser.py::test_isset tests/test_parser.py::test_namespace_names tests/test_parser.py::test_unary_ops tests/test_parser.py::test_assignment_ops tests/test_parser.py::test_object_properties tests/test_parser.py::test_string_unescape tests/test_parser.py::test_string_offset_lookups tests/test_parser.py::test_string_curly_dollar_expressions tests/test_parser.py::test_function_calls tests/test_parser.py::test_method_calls tests/test_parser.py::test_if tests/test_parser.py::test_foreach tests/test_parser.py::test_foreach_with_lists tests/test_parser.py::test_global_variables tests/test_parser.py::test_variable_variables tests/test_parser.py::test_classes tests/test_parser.py::test_new tests/test_parser.py::test_exceptions tests/test_parser.py::test_catch_finally tests/test_parser.py::test_just_finally tests/test_parser.py::test_declare tests/test_parser.py::test_instanceof tests/test_parser.py::test_static_members tests/test_parser.py::test_casts tests/test_parser.py::test_namespaces tests/test_parser.py::test_use_declarations tests/test_parser.py::test_constant_declarations tests/test_parser.py::test_closures tests/test_parser.py::test_magic_constants tests/test_parser.py::test_type_hinting tests/test_parser.py::test_static_scalar_class_constants tests/test_parser.py::test_backtick_shell_exec tests/test_parser.py::test_open_close_tags_ignore tests/test_parser.py::test_ternary tests/test_parser.py::test_array_dereferencing tests/test_parser.py::test_array_literal tests/test_parser.py::test_array_in_default_arg tests/test_parser.py::test_const_heredoc tests/test_parser.py::test_object_property_on_expr tests/test_parser.py::test_binary_string tests/test_parser.py::test_class_trait_use tests/test_parser.py::test_trait tests/test_parser.py::test_trait_renames tests/test_parser.py::test_class_name_as_string tests/test_parser.py::test_static_expressions tests/test_parser.py::test_const_arrays tests/test_parser.py::test_numbers tests/test_parser.py::test_result_multiple_offsets tests/test_parser.py::test_yield tests/test_parser.py::test_static_property_dynamic_access tests/test_parser.py::test_static_property_dynamic_call tests/test_parser.py::test_nowdoc tests/test_parser.py::test_exit_loc
phply/phpparse.py
phply/phpparse.py