Deriving a GIFT grammar (with PEG.js)

Deriving a GIFT grammar (with PEG.js)

by Cris Fuhrman -
Number of replies: 5

I'm following up on a post that was done in 2014 (to which I am unable to reply, perhaps because it's too old?). 

GIFT (or something like it) is a great format because it requires much less clicking to create a lot of questions for quizzes. You can save GIFT in your own text file, in an email, etc. It's an example of a domain-specific language; they are developed to aid in crafting solutions to problems that are specific to certain domains. Creating quiz questions is one such domain

I recently used PEG.js in a project to create a parser for a domain-specific language. It could be useful to consider PEG.js to parse GIFT format. 

The really cool thing about PEG.js is there's a web page that makes grammar development really easy. It's not an IDE, so you have to save your results in a real text file from time to time. You can use sample input, and see the error messages that come from your grammar when it doesn't parse properly.

Here's a start on a grammar that recognizes trivial T/F and MC questions (the input file follows):

Expression
  = Spacing Rule+ EndOfFile

Rule
  = title:QuestionTitle? stem:QuestionStem questionType:SpecificQuestion Space* EndOfLine* 
  { return questionType + ' question:\n ' + title + "\n" + stem }
   / Comment EndOfLine*

SpecificQuestion "(specific question)"
  = TrueFalseQuestion / MCQuestion
 
TrueFalseQuestion "True/False Question"
  = '{' isTrue:('T'/'F') '}' { return isTrue; }

MCQuestion "Multiple-choice Question"
  = '{' EndOfLine choices:(Choice)+ '}' { return "Multiple-choice"; }

Choice "Choice"
  = CorrectChoice / IncorrectChoice
  
CorrectChoice "(correct choice)"
  = '=' correctChoice:RichText EndOfLine { return 'correct choice: ' + correctChoice;}

IncorrectChoice "(correct choice)"
  = '~' incorrectChoice:RichText EndOfLine { return 'incorrect choice: ' + incorrectChoice;}

QuestionTitle
  = '::' title:Title '::' { return ' title: ' + title }
  
QuestionStem
  = stem:RichText { return ' stem: ' + stem; }

Text "(text)"
  = [ A-Za-z0-9.+]

RichText
  = Text* { return 'RichText:' + text() } 

Title
  = Text* { return text() }

_ "whitespace"
  = [ \t]*
  
Spacing 
  = (Space / Comment)*
Comment "(comment)"
  = '//' (!EndOfLine .)* EndOfLine { return 'comment';}
Space "(space)"
  = ' ' / '\t'
EndOfLine "(end of line)"
  = '\r\n' / '\n' / '\r'
EndOfFile 
  = !. { return "EOF"; }

Here's a sample input that parses:

// comment at top
::True statement about Grant::Grant was buried in a tomb in New York City.{T}


::False statement about Grant::Grant was never buried.{F}

// comment in middle

::Math question:: What is 1+2 {
=3
~4
~2
}

I'm pretty sure my grammar above is not perfect - it needs more testing. For example, it doesn't support feedback on answers (e.g. the '#' option). The goal is to show what can be done with PEG and why a grammar for GIFT would be great.

Average of ratings: Useful (1)
In reply to Cris Fuhrman

Re: Deriving a GIFT grammar (with PEG.js)

by Cris Fuhrman -

I've got PEG.js parsing all the GIFT examples I could find. Have a look at the online development environment:

http://peg.arcanis.fr/2xz6e6/

The GitHub repository has automated tests (using node.js and mocha). I've not used the JavaScript objects for anything real, so perhaps there are better ways to format them. The hard part is the parsing, and I think it's mostly done. Hope this is useful to someone.

My next goal would be to write some kind of auto-completion editor for GIFT questions, to make them easier to write. Let me know if you're interested in working on this.

In reply to Cris Fuhrman

Re: Deriving a GIFT grammar (with PEG.js)

by Ali Tavakoli -

I wish I'd found this post earlier smile ; but in any case, here's my contribution: https://github.com/atavakoli/gift-grammar/blob/master/gift.pegjs

It can also parse all of the examples linked from the GIFT format page, and the output is a JSON array of questions/answers. Below Attached is the output for the set of examples linked from the format page.

AFAICT it supports all features except for escape sequences, changes in format, and categories; but, it should be easy enough to expand upon & improve, if there's interest.

Feel free to use this however you'd like!

Average of ratings: Useful (1)