Is there a simple way for integrating Bison/Flex/Yacc into XCode?
I want to write my own language to be parsed, which interacts with my ObjC objects.
But the tools will only take STDIN as input, and will only produce C code, instead of ObjC. They're basically only seem useful for command-line tools, otherwise they need massive pain to override the output every time I regenerate the parser code.
In a nutshell, give your grammar files a .ym extension instead of .y. Xcode will then run Bison with the necessary magic to support Objective-C.
Oddly enough, I found this question because I wanted to do the same thing. I remembered a discussion about it on Apple's cocoa-dev mailing list, but this question came up higher in my Google search. I found the discussion I remembered though, on CocoaBuilder - there's a pretty extensive example at the end. I hope it helps both of us, LOL!
(Edit) Beats the heck out of me how anyone ever managed to find this out, by the way - I still haven't found any official documentation about it.
Xcode does know how to process yacc and flex files, and will automatically compile the generated code files into your project. The trick is figuring out which extensions it expects. In Xcode 4, click on the top-level item in the source list to get the project settings. Click your target in the next list, then Build Rules in the table view header. Scroll down to "System Lex rule" and "System Yacc rule", then hover the cursor over "source files" in each of those to get a tool tip with the extensions it uses for that rule. (…What? That wasn't obvious?)
For Lex, it's: *.l *.lm *.lmm *.lpp *.lp *.lxx
For Yacc, it's: *.y *.ym *.ymm *.ypp *.yp *.yxx
If you have any Objective-C code in your lex/yacc files, you'll need to use the .?m extension to tell Xcode to generate a .m file; likewise, .?mm for Objective-C++. (I'm guessing .?pp, .?p, and .?xx are all C++.) From what I've seen, this Just Works, no Makefile needed. If you want to keep the .flex extension, you can click the "Copy to Target" button in the Lex rule and make a new rule for that extension.
Now the "fun" part is trying to integrate yacc into your code. By default, the yyparse() function which makes the whole thing go expects input from STDIN unless you jump through a bunch of hoops to make it work otherwise. If you're dead-set on using yacc, there's plenty of info on the web about how to bend it to your whims. But you might wind up with fewer keyboard dents on your forehead if you use a modern parser generator like lemon. The syntax is based on yacc's, and it's LALR(1) (whatever that means) so everything you know about shift/reduce conflicts still holds. I found it much easier to work with than yacc/flex.
Edit: I seem to recall that Xcode didn't add the .l file to the build phase automatically, but it did add the .y file. Check your build phases by clicking the top-level item in the Xcode source list, click you target, click the Build Phases table header, then expand the Compile Sources row. If your .l file isn't in there, drag it in from the source list.
I found a great example: https://github.com/epatel/ParserTest. It is 3 years old but works in Xcode 6 and 7.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With