1,074 karma · joined March 31, 2008
Sometimes bytecode VMs appear in unexpected places! A few that I'm aware of:
- eBPF, an extension mechanism in the Linux kernel - DWARF expression language, with interpreters in debuggers like GDB and LLDB - The RAR file format includes a bytecode encoding for custom data transformation
More here: https://dubroy.com/blog/bytecode-vms-in-surprising-places/
Ohm is focused on being easy to use. Grammars are generally very readable, and people love our online editor (https://ohmjs.org/editor/). Performance is fine for many use cases (hobby programming languages, query and schema parsers, etc.) but not good enough for a production programming language.
Chevrotain is much more focused on performance — honestly, it blows Ohm (and some other tools like ANTLR and PEG.js) out of the water. The tradeoff is that writing grammars is a bit more complex than with Ohm, and the result is not as readable.
The current implementation does use a tree-walk interpreter, but I'm considering creating a version that compiles to WebAssembly.
We've been on here a few times before:
• Ohm – A library and language for building parsers, interpreters, compilers, etc.: https://news.ycombinator.com/item?id=26603393 (March 2021)
• Ohm - Parsing Made Easy: https://news.ycombinator.com/item?id=15491336 (Oct 2017)
You might also want to check out WebAssembly from the Ground Up, an online book we're writing that uses Ohm to teach you WebAssembly: https://wasmgroundup.com
From "Acme, A User Interface for Programmers"[2] by Rob Pike:
> Cedar was, however, the major inspiration for Oberon [Wirt89], a system of similar scope but much smaller scale. Through careful selection of Cedar’s ideas, Oberon shows that its lessons can be applied to a small, coherent system that can run efficiently on modest hardware. In fact, Oberon probably errs too far towards simplicity: a single-process system with weak networking, it seems an architectural throwback.
> Acme is a new program, a combined window system, editor, and shell, that applies some of the ideas distilled by Oberon. Where Oberon uses objects and modules within a programming language (also called Oberon), Acme uses files and commands within an existing operating system (Plan 9). Unlike Oberon, Acme has does not yet have support for graphical output, just text. At least for now, the work on Acme has concentrated on producing the smoothest user interface possible for a programmer at work.
[1]: http://www.bitsavers.org/pdf/xerox/parc/techReports/CSL-83-1...
[2]: https://www.usenix.org/legacy/publications/library/proceedin...
But now that I think of it, it couldn't have been true. With Courier 10pt you can fit about 4KB per page. So a 1GB core dump would would 256K pages!
Maybe they weren't examining anything, and it just took that long for them to sign off and allow the core dumps to be sent.
Right, we don't support context-sensitive grammars yet. But we'd like to -- we're just trying to figure out how to do it in a way that fits Ohm's design principles. I'm optimistic that we'll be able to do that.
The big idea in Ohm is its modular semantic actions. You can read more about the design -- and why we think it's interesting -- in our DLS paper: https://ohmlang.github.io/pubs/dls2016/modular-semantic-acti...
If you enable "Explain parse" in the bottom right, you'll see that it shows every single step that the parser takes in interpreting your grammar. It's not perfect, but we think it goes a long way to addressing the debugging issues.
Yes, we are aware that Ohm's batch parsing performance is not great. In practice, it has been fast enough for our uses -- especially since we implemented incremental parsing. With incremental parsing, Ohm's ES5 parser can be as fast as hand-optimized parsers like Acorn.
But you're right, there is definitely room for improvement. So far, we have been much more concerned with making Ohm easy to learn and pleasant to use. I would certainly be happy to have contributors who are interested in improving our batch performance.
We're understand the complaint in [2], but we strongly disagree with Laurie's claim that these are "incorrect" parses. He proposes a different way of handling left recursion, which is just that -- different.
You can find a more thorough discussion here: https://github.com/harc/ohm/issues/55
Another difference is that Ohm grammars can contain left recursion -- both direct and indirect. IMHO this is a pretty big deal, but I know that some people don't agree, and think that avoiding left recursion is not a big problem.
In theory, what you're suggesting should be possible to implement with our incremental packrat parsing algorithm. But we haven't tried it yet, so I can't say for sure.
However, Ohm doesn't really have an "executing environment". It's up to Ohm users to define how their language is interpreted or compiled, by writing semantic actions for the grammar rules. See the second half of the article for an example.
If you're interested, here's the grammar for the language used in the Seymour demo: https://github.com/harc/seymour/blob/6f55361ad3410f42f67f183...
Happy to answer any questions that you have!
> Does Ohm help with type checking in any way?
Not sure what you mean here...are you asking if Ohm has any support for type checking a language that you create using Ohm?
If so, the answer is no -- not yet. But I could definitely imagine implementing a pluggable Semantics that could make this really easy to do for most languages. We are happy to accept pull requests :-)
> Does Ohm support indentation based syntax?
No, it's not (yet) possible to do this directly. Though it can be done with a simple preprocessing step that expands the source code to include explicit indent/dedent tokens.
It's definitely something we'd like to support, we just haven't settled on how.
> Does Ohm handle language composition (eg. JavaScript or CSS inside HTML)?
Yes and no. Right now, the only means of composition Ohm supports is grammar inheritance. This makes sense for things like ES5 and ES6, but not so much for the use case you describe. The problem is that inheritance won't work if you have any name clashes in the grammars.
We've considered something traits-like (http://scg.unibe.ch/archive/phd/schaerli-phd.pdf), but we're not sure whether it's worth the additional language complexity. A simple workaround for the use case you describe is to just parse in two phases: first match the HTML, allowing `any*` inside a script tag, then match the JavaScript inside a semantic action.
If you're interested in more details, you might want to read the paper that we'll be presenting at DLS in Nov: https://ohmlang.github.io/pubs/dls2016/modular-semantic-acti...
> In a sense, we are modelling a mutable object. Implementing that model with immutable data structures does not eliminate the difficulties of dealing with state updates -- it just shifts them to a different conceptual level.