I spent a lot of time today spinning my wheels on the design of the parser, and a lot of time trying to get over mental blocks. These are blocks that seem to stem from my anxiety about the percieved difficulty of the task at hand, and feel like the wrong response because the most effective way of removing my anxiety about work is to actually start working. Also, feeling anxious about work that you want to complete probably isn’t healthy!
So I realized today that I would need backtracking to implement range clauses (and a lot of other statements). It was really, really hard to start even thinking about how to add backtracking to my parser on my own. I ended up roping Bert in to pear-design (heh) this addition to the parser, and it was actually a lot of fun, and I felt like we came up with a reasonably clear design. We designed a one dimensional backtracker: once a grammar requested backtracking, that grammar owned the backtracking, and none of the child-grammars of that grammar could use backtracking themselves. We settled on this because it was the easiest to design and implement, with the expectation that we would modify the backtracker if these constraints were too limiting.
In the middle of implementing the range clause after finishing the one dimensional backtracker, I realized that the tracker needed to be two dimensional in order to parse the range clause correctly. This was my second mental block, and I thought it would be best to take a break. I ended up going out with Bert and Mihai to get food (I got bananas, yum), and then with Dana to geek over vegan things (nobody has given me crap for being vegan in nyc! that shouldn’t be a big deal, but it is. ya’ll rock). When I got back, I still wasn’t in the mood to work, so I opened up a new buffer in emacs, wrote “design of 2D backtracker” at the top, and I thought about how much I really didn’t want to work for the next five seconds. Then I put aside those feelings and started designing the two dimensional backtracker.
To my surprise, I actually finished the design without thinking too much about how I didn’t want to do it, and the design for the two dimensional backtracker was much clearer than the one for the one dimensional backtracker. Implementing it was easy, and I thought I was back on track, until I hit my third mental block of the day: a grammar is invalid if its type is an error type, OR if any of its children are error types, OR if any of its children’s children are error types, etc! I wasn’t checking any of grammar’s children’s types, and that meant that I wouldn’t be able to accurately say if a grammar was invalid.
The change involved in order to see if a type is valid is substantial and tedious: each node needs a method that checks to see if any of its children are an error type. And I have like 30 different types of nodes ;_; (there’s probably a fair amount of redundancy, but I’m planning on cutting them down after I finish the parser). And that’s the mental block I’m stuck on now. I went home early to rest. I want to get a lot of sleep tonight and come in early tomorrow morning to start implementing this error checking method.
I am unsure of what my behavior should be when I get to a mental block. I took advantage of the ability to be social and productive with Bert to get over my first mental block, and my “think terrible thoughts and then put them aside” method worked for the second mental block, but I felt as if I had no way to tackle the third mental block, and I basically killed time until presentations. But with all three mental blocks, I still spent a significant amount of time staring at the computer screen feeling overwhelemed by the task at hand. That feels wrong; I want to come up with a systematic way to either get over mental blocks, or sidestep them long enough to come back with a fresh mind.
For those of you reading this who have tackled similar issues, I’d like to hear what has worked for you.