Grammars with "&convert=SomeEnum($$)" do not compile with hilti-build and pac-driver
Opened this issue · 4 comments
If I try to compile the following minimal grammar with
hilti-build -o a.out tools/pac-driver/pac-driver.cc libbinpac/parsers/minimal.pac2
, and get an error message from hiltic, see below. If I do not use convert
but the line without it (see code), the compilation terminates successfully. Additionally, when running the grammar with pac-driver
's JIT, there is no problem with convert
.
Minimal grammar:
module Profinet;
import BinPAC;
type EtherType = enum {
IPV4 = 0x800,
ARP = 0x806,
Wake_on_LAN = 0x842
};
export type EthernetPacket = unit {
destination: bytes &length=6;
source: bytes &length=6;
ethertype: uint<16> &convert=EtherType($$);
# ethertype: uint<16>;
payload: bytes &eod;
on %done {
print self.ethertype;
}
};
Error message:
>>> Undef
profinet.hb3547.tmp.hlt:714-714: error, unknown ID Undef [pass::hilti::IdResolver]
profinet.hb3547.tmp.hlt: Aborting due to verification error.
error running hiltic, aborting
Part of profinet.hb3547.tmp.hlt
:
@if_true_23
struct.set __self "ethertype" Undef
jump @if_cont_23
I tried the included grammars pcap.pac2
and tftp.pac2
, they have the same problem with hilti-build
, but not with pac-driver
.
hilti-build goes through intermediary *.hlt files on disk. Unfortunately there are still some issues where those files end up using constructs that the subsequent read cannot parse back in. That's a mismatch between the codes for reading and writing HILTI code.
The pac-driver executable avoids this issue by doing all work just-in-time in RAM.
Thanks for the explanation. I'll stick with pac-driver for the moment then. I'll comment back here if this issue becomes more important for my project to ask how this can be fixed.
Indeed it would be important for us if this would work. Are there plans to fix these issues? Or could you please point me to the points in the code that would need to be fixed?
Nobody looking at that right now. The two main parts involved here are (1) the printer in hilti/passes/printer.cc
(which renders an in-memory AST into HILT source code), and (2) the parser in parser/parser/parser.yy
(which does the opposite :). Ideally, parsing the output of (1) with (2) would yield back the same AST; however the two don't always match up right now.
The test-suite has actually a separate mode to test this: running btest -a printer
runs the tests through the print/parse cycle before executing (see comment at beginning of tests/Scripts/filter-printer
). However, making this mode pass isn't enforced so far (which is a mistake) and I haven't tried/used it in a quite a while.