Skip to content
Snippets Groups Projects
  1. Feb 14, 2020
  2. Feb 09, 2020
    • Sven M. Hallberg's avatar
      add H_FIELD_TOKEN() to match H_INDEX_TOKEN() · 0795591a
      Sven M. Hallberg authored
      this omission has nagged me a number of times and i think it must have been a
      simple oversight.
      0795591a
    • Sven M. Hallberg's avatar
      put a type assert macro for the sequence in H_INDEX/H_FIELD · bd5cadf2
      Sven M. Hallberg authored
      this way the assert will fire from the user's code rather than the one in
      glue.c:h_seq_index() which is not informative without a stack trace.
      bd5cadf2
    • Sven M. Hallberg's avatar
      avoid a segfault when h_act_flatten() is called on a null token · 6ab2adf1
      Sven M. Hallberg authored
      also includes commented-out tests for functionality that i discovered we never
      provided, namely position and length information at the granularity of
      HParsedTokens. at the moment, these fields always seem to be 0. we should
      probably fix that or get rid of them. in the latter case it might make sense
      to move this information to HParseResult, so the user can get access to it via
      h_action() as needed.
      6ab2adf1
    • Sven M. Hallberg's avatar
      differantiate error codes from h_compile() and update documentation · 0813b699
      Sven M. Hallberg authored
      the regex backend already returned 2 for an internal failure, contrary to
      documentation, so this mainly brings the latter in line with existing behavior.
      
      at the same time, fix a bug: h_compile would previously return "false" (0) on
      exceptions (longjmp).
      
      make use of our new freedom to signal different error conditions from the
      context-free backends, notably "incompatible combinator" vs. "unresolvable
      conflict".
      0813b699
  3. Feb 03, 2020
  4. Jan 12, 2020
  5. Jan 11, 2020
  6. Jan 07, 2020
  7. Dec 09, 2019
  8. Dec 05, 2019
  9. Dec 03, 2019
  10. Dec 02, 2019
  11. Nov 30, 2019
  12. Nov 29, 2019
  13. Nov 28, 2019
  14. Nov 26, 2019
    • xentrac's avatar
      Fix bug #19 in permutations and sequences too · 032430e3
      xentrac authored
      In `h_sequence__ma` the same bug occurs, and it manifests as a crash
      in the same way, so I've added a test for it.  In `h_permutation__ma`
      it evidently exists in the same form, but I haven't figured out how to
      reproduce it; in that case I added a fix to the implementation, but no
      test.
      032430e3
    • xentrac's avatar
      Add regression test for bug #19 · 302f2f9f
      xentrac authored
      I committed the fix for bug #19 without a test because I didn't know
      how our test worked yet; here's a test.
      
      A somewhat more desirable way to do this would be to commit the
      test *first*, marked as "incomplete" with `g_test_incomplete()` (an
      expected failure).  However, `g_test_incomplete()` does not handle
      segfaults!  There's no way to mark a segfaulting test as an "expected
      segfault".  So if you want to verify that this test reveals the bug,
      you'll need to `git show thiscommit | patch -p1` or something, in a
      tree that doesn't have the fix applied.  Or you can comment out the
      fix, I guess.
      302f2f9f
  15. Nov 23, 2019
    • xentrac's avatar
      Fix #19, GLR backend reaches unreachable code · 9e662b68
      xentrac authored
      Original behavior:
      
          hammer/build/debug/src/bindings/python$ LD_LIBRARY_PATH=. gdb python
          ...
          (gdb) r
          ...
          Python 2.7.6 (default, Nov 12 2018, 20:00:40)
          [GCC 4.8.4] on linux2
          Type "help", "copyright", "credits" or "license" for more information.
          >>> if 1:
          ...     import hammer as h
          ...     h.choice(h.ch_range('0', '9'), h.ch_range('A', 'Z'), h.ch_range('a', 'z')).compile(h._PB_GLR)
          ...
      
          Program received signal SIGSEGV, Segmentation fault.
          0xb79ecab2 in collect_nts (grammar=0x836abe0, symbol=0xb7d550a4)
              at build/debug/src/cfgrammar.c:120
          120	      for(x = (*s)->items; *x != NULL; x++) {
          (gdb) bt
          #0  0xb79ecab2 in collect_nts (grammar=0x836abe0, symbol=0xb7d550a4)
              at build/debug/src/cfgrammar.c:120
          #1  0xb79ecacd in collect_nts (grammar=0x836abe0, symbol=0x836ab58)
              at build/debug/src/cfgrammar.c:121
          #2  0xb79ec90a in h_cfgrammar_ (mm__=0xb79ff4b4 <system_allocator>,
              desugared=0x836ab58) at build/debug/src/cfgrammar.c:66
          #3  0xb79e8207 in h_lalr_compile (mm__=0xb79ff4b4 <system_allocator>,
              parser=0x836ab40, params=0x0) at build/debug/src/backends/lalr.c:280
          #4  0xb79e634a in h_glr_compile (mm__=0xb79ff4b4 <system_allocator>,
              parser=0x836ab40, params=0x0) at build/debug/src/backends/glr.c:15
          #5  0xb79f0eef in h_compile__m (mm__=0xb79ff4b4 <system_allocator>,
              parser=0x836ab40, backend=PB_GLR, params=0x0)
              at build/debug/src/hammer.c:97
          #6  0xb79f0e9d in h_compile (parser=parser@entry=0x836ab40, backend=PB_GLR,
              params=params@entry=0x0) at build/debug/src/hammer.c:92
          #7  0xb7a54ca4 in HParser__compile (backend=<optimized out>, self=0x836ab40)
              at hammer_wrap.c:3567
      
      New behavior:
      
          hammer/build/debug/src/bindings/python$ LD_LIBRARY_PATH=. gdb python
          ...
          (gdb) r
          ...
          Python 2.7.6 (default, Nov 12 2018, 20:00:40)
          [GCC 4.8.4] on linux2
          Type "help", "copyright", "credits" or "license" for more information.
          >>> if 1:
          ...     import hammer as h
          ...     h.choice(h.ch_range('0', '9'), h.ch_range('A', 'Z'), h.ch_range('a', 'z')).compile(h._PB_GLR)
          ...
          True
          >>> ^D
          [Inferior 1 (process 19621) exited normally]
          (gdb) quit
      
      After thrashing about for a few hours, this was the crucial clue:
      
          >>> import hammer as h
          >>> h.choice(h.ch('0')).compile(h._PB_GLR)
          ==18856== Conditional jump or move depends on uninitialised value(s)
          ==18856==    at 0x4A34FE9: h_desugar (desugar.c:7)
          ==18856==    by 0x4A2D150: h_desugar_augmented (lalr.c:261)
          ==18856==    by 0x4A2D1F7: h_lalr_compile (lalr.c:280)
          ==18856==    by 0x4A2B349: h_glr_compile (glr.c:15)
          ==18856==    by 0x4A35EEE: h_compile__m (hammer.c:97)
          ==18856==    by 0x4A35E9C: h_compile (hammer.c:92)
          ==18856==    by 0x49B0CA3: HParser__compile (hammer_wrap.c:3567)
      
      The particular thing that it's saying is uninitialized seems to be
      
            if(parser->desugared == NULL) {
      
      The `parser` in question is the `HParser` we're trying to desugar,
      which is presumably the choice object created by `h.choice`, which
      seems to be invoking `h_choice__a`:
      
          def choice(*args): return _h_choice__a(list(args))
      
      That was implemented as follows:
      
          HParser* h_choice__a(void *args[]) {
            return h_choice__ma(&system_allocator, args);
          }
      
          HParser* h_choice__ma(HAllocator* mm__, void *args[]) {
            size_t len = -1; // because do...while
            const HParser *arg;
      
            do {
              arg=((HParser **)args)[++len];
            } while(arg);
      
            HSequence *s = h_new(HSequence, 1);
            s->p_array = h_new(HParser *, len);
      
            for (size_t i = 0; i < len; i++) {
              s->p_array[i] = ((HParser **)args)[i];
            }
      
            s->len = len;
            HParser *ret = h_new(HParser, 1);
            ret->vtable = &choice_vt;
            ret->env = (void*)s;
            ret->backend = PB_MIN;
            return ret;
          }
      
      Indeed it does not seem to have been initializing `desugared`.  Fixing
      this cures this symptom.
      
      Other things it's probably worth checking out:
      
      - Are there other places where we create HParser objects where one or
        more fields may be uninitialized?
      - Perhaps `h_new` should zero the memory it returns, since it's only
        used for fixed-size objects and not things like variable-size
        character buffers?
      9e662b68
  16. Nov 21, 2019
    • xentrac's avatar
      Get JNI shared library to build with SCons · 2fd2a1d8
      xentrac authored
      This was a real adventure since I didn’t know anything about SCons, and
      I can’t say that I’m fond of scons after it, but it does seem to work.
      There were two obstacles.
      
      First, the ConfigureJNI module doesn’t successfully configure the JNI on
      my system because it was expecting to find `JAVA_HOME` in .., so I added
      a little code to notice if it’s failing to find a place where `jni.h`
      exists.  (And on my system I did `export
      JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64` before running it, but your
      pathnames will vary.)  There was a hardcoded pathname in SConscript,
      presumably as an interim debugging measure, which I removed.  A
      reasonable default to try on Debian-derived systems such as Ubuntu and
      LinuxMint might be `/usr/lib/jvm/default-java`, but I didn’t implement
      that.
      
      Second, in SConscript, the JNI include directories were being stuck into
      a `javaenv` SCons environment object, which was used to build the Java
      classes providing the Java interfaces to Hammer, but not the C files
      containing the native methods themselves.  Consequently the compiler
      couldn’t find the JDK JNI headers when it tried to compile the C code
      into a shared library.  It might make sense to use `javaenv` to compile
      that shared library, but in case it doesn’t, I cloned the default
      environment with an extra include directory.
      
      I hope this is soon enough to be helpful!
      2fd2a1d8
  17. Nov 20, 2019
Loading