📜  ohm (1)

📅  最后修改于: 2023-12-03 15:03:21.566000             🧑  作者: Mango

Ohm

Ohm is a library for creating parsers, interpreters, and compilers. It provides a parsing library that generates a parser in JavaScript from a PEG grammar, with support for left-recursion and memoization. Ohm also supports the construction of interpreters and compilers in JavaScript via semantic actions.

Features
  • Generates parsers in JavaScript from PEG grammars
  • Supports left-recursion and memoization for efficient parsing
  • Supports the construction of interpreters and compilers via semantic actions
  • Provides the ability to write code with a natural syntax, while still providing the full power of JavaScript for semantic actions
Getting Started

To get started with Ohm, you can install it via NPM:

npm install ohm-js

You can then use Ohm to define a grammar and generate a parser:

const ohm = require('ohm-js');

const grammar = ohm.grammar(`
  Greeting {
    hello = "Hello" name "!"
    name = ~letter+
  }
`);

const parser = grammar.createParser();

const result = parser.parse('Hello World!');
console.log(result.succeeded());

This will output true, indicating that the input string was successfully parsed by the generated parser.

Example: Simple Calculator

Here is an example of defining a simple calculator grammar in Ohm and using it to evaluate expressions:

const ohm = require('ohm-js');

const grammar = ohm.grammar(`
  Calculator {
    Exp = AddExp
    AddExp = AddExp "+" MulExp   -- plus
           | AddExp "-" MulExp   -- minus
           | MulExp
    MulExp = MulExp "*" PriExp   -- times
           | MulExp "/" PriExp   -- divide
           | PriExp
    PriExp = "(" Exp ")"        -- parens
           | number
    number = digit+

    space += " "
  }
`);

const semantics = grammar.createSemantics();
semantics.addOperation('eval', {
  Exp: function(e) { return e.eval(); },
  AddExp_plus: function(x, op, y) { return x.eval() + y.eval(); },
  AddExp_minus: function(x, op, y) { return x.eval() - y.eval(); },
  MulExp_times: function(x, op, y) { return x.eval() * y.eval(); },
  MulExp_divide: function(x, op, y) { return x.eval() / y.eval(); },
  PriExp_parens: function(open, e, close) { return e.eval(); },
  number: function(digits) { return parseInt(this.sourceString, 10); }
});

const input = '(1 + 2) * 3';
const match = grammar.match(input);
if (match.succeeded()) {
  const result = semantics(match).eval();
  console.log(`${input} = ${result}`);
}

This will output (1 + 2) * 3 = 9, indicating that the input expression was successfully parsed and evaluated by the grammar.

Conclusion

Ohm is a powerful and flexible library for creating parsers, interpreters, and compilers. It provides a simple and intuitive syntax for defining grammars, as well as powerful tools for constructing interpreters and compilers. Whether you are building a simple calculator or a complex programming language, Ohm has the features you need to get the job done efficiently and effectively.