Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple inheritance (and foreign rule invocation) #201

Closed
philippotto opened this issue May 8, 2017 · 7 comments
Closed

Multiple inheritance (and foreign rule invocation) #201

philippotto opened this issue May 8, 2017 · 7 comments

Comments

@philippotto
Copy link

Hello,

As far as I understand, Ohm does not support multiple inheritance for extending grammars, right? I might be working on this within the scope of my master's thesis and would appreciate some pointers.

Maybe you can tell me, if there was already some work done for achieving this or which parts of the code would need to change for this (I'm not familiar with the code base, yet). I'm aware of the fact that multiple inheritance introduces a new class of problems, but I'd like to try out a "quick" solution which does not deal with conflicts for now.

Thank you
Philipp

@pdubroy
Copy link
Contributor

pdubroy commented May 8, 2017

Hi Philipp,

That's correct, we don't currently support multiple inheritance. In the past, we have discussed supporting something like mixins or traits (http://scg.unibe.ch/archive/phd/schaerli-phd.pdf), but there is still some debate as to whether the added complexity would be worth it.

If you want to experiment with this, I'd suggest first focusing on manipulating the grammar objects themselves. Specifically, take a look at the rules property -- you can implement some form of mixins/traits just by manipulating this object directly. This will let you easily experiment with different approaches without having to worry about modifying the Ohm syntax.

If you look at the definition of Grammar.ProtoBuiltInRules, you can see how it's possible to construct a rule dictionary by hand. To see how a rule is looked up in the rule dictionary, take a look at the reallyEval method in pexprs-eval.js.

As a next step, you might propose an API / internal DSL that would expose the feature and let people try it out. If you can figure out a sensible semantics (and have a few compelling examples to convince everyone that it's worth implementing) the final step would be to implement the syntax. But I think you can make a lot of progress on the problem without worry about syntax just yet.

Hope that helps, and let me know if you have any more questions.

@philippotto
Copy link
Author

Thank you, Patrick, this is really helpful. I will give it a try and let you know if/when I achieved something presentable.

@pdubroy
Copy link
Contributor

pdubroy commented May 8, 2017

Great, sounds good! Feel free to share your in progress work too. I'm definitely interested in this and would be happy to discuss things even if you haven't worked all the kinks out.

@alexwarth
Copy link
Contributor

alexwarth commented May 8, 2017 via email

@philippotto
Copy link
Author

philippotto commented May 15, 2017

Hi Alex,

Thanks for the reference! I found some time to play with the foreign rule invocation mechanism of OMeta and have a question. Let's assume I have two subclasses of the OMeta JSParser which both extend primExpr. Now I want to "combine" these classes using foreign rule invocation.

My current approach looks like this:

eval(readFile('Compiled_JavaScript_Compiler'))

// Map a?.b expressions to cond(a, function(p) { return p.b })
ometa CondJSParser <: JSParser {
   primExpr = primExpr:p
                 ( "?" "." "name":m "(" listOf(#expr, ','):as ")" -> [`call, [`get, "cond"], p, [`func, [`p], [`send, m, [`get, `p]]]]
                 | "?" "." "name":f                               -> [`call, [`get, "cond"], p, [`func, [`p], [`getp, [`string, f], [`get, `p]]]])
                 | super("primExpr")
}

// Basically the same as CondJSParser, only with a bang notation:
// Map a!.b expressions to cond(a, function(p) { return p.b })
ometa BangJSParser <: JSParser {
   primExpr = primExpr:p
                 ( "!" "." "name":m "(" listOf(#expr, ','):as ")" -> [`call, [`get, "cond"], p, [`func, [`p], [`send, m, [`get, `p]]]]
                 | "!" "." "name":f                               -> [`call, [`get, "cond"], p, [`func, [`p], [`getp, [`string, f], [`get, `p]]]])
                 | super("primExpr")
}

ometa UnionParser <: JSParser {
  primExpr = foreign(BangJSParser, `primExpr) | foreign(CondJSParser, `primExpr) | super(`primExpr)
}

i = "a!.b + a?.b"  // does not match
// i = "function() { a!.b }; function() { a?.b }" // matches

a = UnionParser.matchAll(i, "topLevel")
b = JSTranslator.match(a, "trans")

If the new syntax constructs are in different expressions (e.g., if there are within different functions), the parser succeeds, but if the new constructs are in the same expression it fails. I can see why it fails (I assume, since the input is "forwarded" to one parser at a time and the primExpr rule of the UnionParser is not used in recursive matches). However, is there any possibility to achieve what I want with the foreign rule invocation? If not, I would probably try to extend OMeta so that it's possible.

By the way, my long-term goal is to research mechanisms for handling conficts which can arise in these kind of compositions of modular extensions.

Cheers,
Philipp

@pdubroy
Copy link
Contributor

pdubroy commented Aug 27, 2020

Closing this issue for housekeeping purposes, since I don't think we will be implementing multiple inheritance anytime soon.

@pdubroy pdubroy closed this as completed Aug 27, 2020
@pdubroy pdubroy changed the title Multiple inheritance Multiple inheritance (and foreign rule invocation) Aug 27, 2020
@pdubroy
Copy link
Contributor

pdubroy commented Aug 27, 2020

Tracking the feature request for foreign rule invocation in #191.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants