Lately I've been playing with writing my own programming language, following the excellent Crafting Interpreters book but I've hit something of a snag.

I'd like to extend the parser to accept variable declarations in the form of: var x,y,z and to allow for unpacking like [x,y,z]=[1,2,3] (noting that jlox doesn't, as yet, support arrays). Finally I'd like to allow for an in statement so you can do: for(x in a) or to test:

var a = {'Larry': 1, 'Curly': 2}
var x = 'Moe'
var b = x in a
print b

Output should be false. That is: the in statement is context-sensitive because it behaves as both an assignment/iterator statement as well as a boolean test. This context-sensitivity is especially problematic because while parsing you'd have to employ some sort of lookback to see if you're in a loop declaration or if you're "just an expression."

Anyway - given jlox - I was wondering if there's something trivial I'm missing to implement the above, or if it's going to be a rather hairy task?

  • 1
    (1) What exactly is your question here? An open-ended “I was wondering …” is not a focused, answerable question. (2) What kind of parser are you using? The different uses of x in a are not ambiguous for any top-down parser, but would be a reduce/reduce conflict for LR. – amon Nov 6 '17 at 18:28
  • The problem seems to me that for(EXP) BODY is already valid Lox. In this case you might want to keep in just for the check, and use. e.g. for(x of seq) for iteration (see JavaScript). – Jasmijn Nov 6 '17 at 18:37
  • Also @amon, OP seems to be referring to github.com/munificent/craftinginterpreters – Jasmijn Nov 6 '17 at 18:38
  • If the parser is hard to write, the language will be hard to write in as well. – Frank Hileman Nov 6 '17 at 20:09
  • The in in for(x in a) has to be part of the syntax for the loop, just like the tokens x and a has to be separate tokens. Otherwise, if it was just a for(expr), you would have a lot of difficulties later actually iterating a and making the name x available in the loop body. – poke Nov 14 '17 at 10:14

You may be able to work around it by "segregating" a bit the "id in Expr" construct at the grammar level.

For instance, Grammophone reports the following as being LL(1), LALR(1), LR(1) :

Stmts -> Stmt Stmts | .

Stmt -> for ( id InExpr ) { Stmts } | Expr | Let .

Let -> var id = Expr .

InExpr -> in Expr .

Expr -> id .

Which, granted, doesn't completely solve your problem, but gets you closer; if you have chosen to go with a top-down parser, you'll only need it to have more lookahead (ie, than LL(1)) for its "Let" parsing procedure to handle the "var id = id in Expr" case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.