1

Because the Scala Parsers library requires that you subclass Parsers, which leaves you with a specific Parser implementation in the end, it seems like you can't really separate it out into multiple classes or objects, unless they are inside the scope of the class that originally subclassed Parsers. What is the proper way of dealing with this, so that I don't have to just have 50 lazy vals in a row?

2 Answers 2

2

Personally, I think the way to do it is keep all in one class or, if it makes sense, make a single inheritance hierarchy to expand upon concepts, just like JavaTokenParsers extends RegexParsers which extends Parsers. Also, use of tokenized parsers helps a bit, by splitting lexical from the grammar.

Other than that, keep it in one place: splitting a grammar makes for a nightmare of understanding. All the rest -- the AST classes, and the code that operates on them, need not be kept with the parser.

Now, if that really isn't to your test, you can split them in traits, and use self types to create the necessary dependencies between the traits. You them just make one big class (or object) which inherits from all traits.

Sign up to request clarification or add additional context in comments.

5 Comments

What do you mean by tokenized parsers? Does that just mean parsers with separate rules for each token type?
@DaoWen I mean parsers that do not read strings, but tokens. The tokens are produced by lexers which take care of such low level details. That's how traditional compilers works: lex + yacc. See the json parser in the standard library for an example.
@DanielC.Sobral, I tried implementing this, and ran into trouble with making a single inheritance hierarchy, in that the types resolve differently, with the parent.Parser and child.Parser being considered different types. How can you resolve that with self types?
@nnythm You might not believe this, but I can't even think what's causing problem for you. Please give examples and error messages.
@DanielC.Sobral you were right, I fiddled around with it and the only thing that was giving me a problem was that I was using the multiple constructor pattern incorrectly, I had forgotten to move my object into the same trait as the class it was constructing for.
1

You can split the different components into traits extending the same parent Parser type, and then mix them together to create your final parser. Obviously some of the parser combinators will be dependent on others, but at least the basic parsers (e.g. terminal parsers) could be factored out this way. You probably don't want to split it into too many different classes/traits anyway otherwise it could get very hard to analyze what the parser is doing if the code is split across too many different files.

4 Comments

This seems like a good idea, but how can they inherit from the parent Parser when they are outside of my class that inherits Parsers?
I have a group of parsers that are organized something like this. There is a Core parser that extends RegexParsers, and it contains a bunch of parsers for the most basic terminals and non-terminals in my grammars. All of the other traits extend this trait since they build off of these terminals and non-terminals. My final parser classes extend the Core parser and mix a few of the other parser traits to make a complete parser.
@nnythm What is the problem you see? A trait can inherit from a class.
@DanielC.Sobral I thought that when X extends Parsers, that X.Parser was private[X], but I just tried it out and I was wrong. I think I get it now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.