Filed under:
Code

Lemon is a parser generator - a tool which takes a context-free grammar and converts it into code which can parse a file using that grammar. It’s a very useful tool, but can be a bit fiddly to get set up when building an app with Xcode. It’s fiddly because it’s not the grammar file which gets compiled into your app, but the code generated from it.

This post will describe how to integrate both the Lemon tool and the converting of the grammar into an Xcode build.

Sample Code

A sample project including the code from this post can be downloaded from GitHub.

Setup

You will need to add the two files required by Lemon to your project. These are lemon.c and lempar.c. The former is the generator itself and the latter is a template file for the generated code. These are under source control in the SQLite fossil repository.

Building the Lemon tool

Before we can do anything else, we need to build the Lemon tool itself. In this example, we will do it as part of building the demo app. To do this, select the project in the project navigator and add a new Run Script build phase. Drag this build phase to be the first item and enter the following command:

clang -o "${DERIVED_FILES_DIR}/lemon" "${PROJECT_DIR}/LemonDemo/lemon.c"

And add an entry to the output files table below with the text:

$(DERIVED_FILE_DIR)/lemon

Your new build phase should look like this:

Xcode build rule showing code

Now, each time you build your app, the lemon binary will be built along with it.

Creating the parser code from a grammar

Next, we have to tell Xcode how to compile the grammar files using the freshly-built tool. To do this, add a build rule to your Xcode project to build files with names matching *.lemon. In the custom script area, insert the following code:

// Copy the grammar and template files to an intermediate directory
cp "${INPUT_FILE_PATH}" "${DERIVED_FILES_DIR}"
cp "${PROJECT_DIR}/lempar.c" "${DERIVED_FILES_DIR}"

// Build the parser from the grammar
cd "${DERIVED_FILES_DIR}"
"${DERIVED_FILES_DIR}"/lemon "${DERIVED_FILES_DIR}/${INPUT_FILE_NAME}"

// Change the file extension to allow Objective-C code in the grammar
cp "${INPUT_FILE_BASE}.c" "${INPUT_FILE_BASE}.m"

This script copies the C template file and grammar to an intermediate folder and builds it using the lemon tool. It then copies the built file from a .c extension to .m so that you can use Objective-C code in your grammar file.

You will also need to enter the expected output files below the script. Here you should add the following entries:

$(DERIVED_FILES_DIR)/$(INPUT_FILE_BASE).h
$(DERIVED_FILES_DIR)/$(INPUT_FILE_BASE).m

This is an important step! The output files are those that will be included by Xcode when building your app. Your build rule should now look like this:

Xcode build phase showing code

Finished!

Now your project is ready to build *.lemon grammar files into a parser. As you can see, integrating generated code is not a difficult task, but one that needs a little care to make sure it works correctly. Just remember the steps in order:

  1. Build the tool
  2. Use the tool to build the parser from the grammar
  3. Use the parser in your app

If there is interest, I will follow this up with a post describing how to write a basic grammar to parse particular texts. If you want to take a peek ahead, there’s more detail in the sample code for this demo.

Filed under:
Code

Got a couple of pieces of AppleScript for starting and stopping Apache and MySQL which are too small to be worth posting as downloads. I don’t use these any more, but they were handy for custom installs of Apache/MySQL.

Starting: do shell script "/sw/sbin/apachectl start" password "MYPASSWORD" with administrator privileges do shell script "/usr/local/mysql/bin/mysqldsafe > /dev/null 2>&1 &" password "MY_PASSWORD" with administrator privileges

Stopping: do shell script "/sw/sbin/apachectl stop" password "MYPASSWORD" with administrator privileges do shell script "/usr/local/mysql/bin/mysqladmin -u root -pROOTMYSQLPASSWORD shutdown" password "MYPASSWORD" with administrator privileges

You will obviously need to change MYPASSWORD to your admin password. You need to change ROOTMYSQLPASSWORD to your root MySQL password, or another user name/password combo with shutdown privileges. Note: there should not be a space between -p and ROOTMYSQL_PASSWORD.

Also, the path to apache/mysql might need changing. You can find out where they are by running which apachectl and which mysqld_safe in the terminal.

Just paste the code into Script Editor, and save how/wherever you like. I save mine as run-only executables which show up nicely in Quicksilver.

Can’t remember where this code originally came from, but it’s pretty handy, so thanks whoever pointed me at this.

Filed under:
Code
CakePHP

Important! This is old code. I’ve not used it for a long time. It might still be useful. Be careful.

 

This snippet is a CakePHP component which can be used to force a users browser to download a specified file instead of attempting to display it. It will happily deal with any file your scripts have read access to. When provided with an absolute file location and filename for the downloaded file, it will attempt to look up an appropriate mime-type for the file, output some HTTP headers followed by the file data itself.

You are responsible for exiting after calling this method. Not exiting will result in CakePHP trying to render a page after sending the file data, causing (possibly invisible) errors. I have also removed error checking code responsible for checking the file path and download name as it is very app-specific. You will probably want to add your own.

Note: I have not tested this on a Windows-based machine. I don’t see why it shouldn’t work, but you have been told.

 

Usage

var $components = array('ForceDownload') ... $this->ForceDownload->forceDownload('/path/to/file.php', 'MyPHPFile.php'); exit();

 

Download force_download.zip

Filed under:
Code
CakePHP

Important! This is old code. I’ve not used it for a long time. It might still be useful. Be careful.

 

Favatars is a Wordpress plugin for displaying favicons as avatars next to blog post comments. This code is an adaptation of the original work to turn it into a CakePHP Controller. When given a URL, it will attempt to locate a favicon for that site. If one is found, it is cached and displayed. If not, it will display a default image.

By using this controller within<img> tags, favicons can be used as images anywhere within your site, without knowing their specific address. It is currently in use on this blog and favicons will appear next to post comments.

Instructions for use are included in the download. I can no longer offer support for this code.

Favatars.zip

Filed under:
Code

 

Important! This is old code. I’ve not used it for a long time. It might still be useful. Be careful.

This code parses iCalendar  (RFC 2445) compliant files into nested associative arrays. It doesn’t do the full iCal specification, as I only needed a subset of it, but the code is easily extended and should just ignore anything it doesn’t understand. It’s old and currently unused by me, but should still work!

I’d love to hear back from anyone who uses this. If you send changes, I’ll merge them into the download.

 

 

Download:

PHP iCal Parser