I can handle this case:
a
b
c
d
e
f
g
h
That is, if it's entirely indented with tabs/spaces/whatever.
I can handle this case:
a
b
c/d
e/f/g
h
That is, indentation with mixed tabs and slashes, with nothing under the slash'd lines. But this?
a
b
c
d
e/f
g
h
Can't figure out how to do it. Everything I've tried so far can't parse 'g' correctly (Parses it as under 'e', rather than under 'f') or can't parse 'h' properly (Parses it as under 'e', not under 'a').
That construct is legal in DM, I'm certain, but I can't for the life of me figure it out. And because DM is the only language I know of (And I've done some searches about it) that uses indentation to indicate block structure but allows that use of slashes, I don't have any examples to crib off of.
I'm using flex and bison - I'm getting the lexer to figure out the block structure (So technically it's not a parsing issue, but whatever) and then passing definitions up to bison with the block level set in a global variable. Any ideas on how to handle it? This is the most correct I've got at the moment:
%{ int depth = 0; %} %% [\t ] depth++; \n depth = 0; \/ depth++;
EDIT: Wait, no, I came up with a solution:
%{ #include struct depth_t { int depth; int tabdepth; } typedef depth_t; int depth = 0; int tabdepth = 0; depth_t tempdepth; std::vector<depth_t> stack; %} %% [\t ]* { depth+=yyleng; tabdepth+=yyleng; tempdepth = stack.back(); if(tempdepth.tabdepth < tabdepth) { depth = tempdepth.depth + tabdepth - tempdepth.tabdepth; } else { stack.pop_back(); } } \n { tempdepth.tabdepth = tabdepth; tempdepth.depth = depth; stack.push_back(tempdepth); tabdepth = depth = 0; } \/ depth++;
That appears to work, although I can't help but feel that I'm overcomplicating issues... And of course, it won't work with braces. That's easy, though.
EDITEDIT: That's a vector of depth_ts, of course. For some reason the <depth_t> got cut out, even though I've got <pre> tags around it. Is that a bug?
EDITEDITEDIT: More issues! You wouldn't believe it, but it took me this long to realise that / is also used for the division operator. That means block depth is going to have to be determined at the parser level. Crap. I think it'll mostly convert, but I'm not sure how I'll have the grammar distinguish between, for example:
a/b //Defines /a and /a/b
world/New()
var
a
b
a/b //Does nothing
without making the parsing much more complicated than I had originally invisioned. Ah well, such is life. I suppose I can just ignore everything with a tab-depth greater than a function... and I can tell its a function because it has () at the end of it.