Skip to content

Instantly share code, notes, and snippets.

@jcamins
Last active December 21, 2015 09:19
Show Gist options
  • Select an option

  • Save jcamins/6283892 to your computer and use it in GitHub Desktop.

Select an option

Save jcamins/6283892 to your computer and use it in GitHub Desktop.
Query syntax
/* description: Parses Biblionarrator queries. */
/* lexical grammar */
%lex
%%
\s+ /* skip whitespace */
"(" return 'GS';
")" return 'GE'; // Group End
(keyword|author|title)\: return 'INDEX'
"!" return 'NOT'; // Not
"||" return 'OR'; // Or
"&&" return 'AND'; // And
["][^"]*["] return 'PHR'; // Phrase
[^\s()!:|&]+ return 'WORD'
<<EOF>> return 'EOF';
/lex
/* operator associations and precedence */
%right OR AND
%left NOT
%start plan
%% /* language grammar */
plan
: query EOF
{ /*typeof console !== 'undefined' ? console.log($1) : print($1);*/
return $1; }
;
query
: query AND query
{ $$ = [ 'AND', $1, $3 ]; }
| query OR query
{ $$ = [ 'OR', $1, $3 ]; }
| NOT query
{ $$ = [ 'NOT', $2 ]; }
| query query
{ $$ = [ 'AND', $1, $2 ]; }
| node
{ $$ = $1; }
| explicit_group_start query explicit_group_end
{ inspect(yy.indexStack); $$ = $2; }
;
explicit_group_start
: GS
{ if (!yy.indexStack) yy.indexStack = [ /*curindex ||*/ 'keyword' ]; }
// These contortions make it possible to maintain a default index stack,
// but as it turns out, following the close of an explicit group the user
// is more likely to expect a return to the 'keyword' index than a return
// to the last-set index prior to the explicit group. I am leaving the
// code because it took me ages to figure it out, and I don't want to lose
// it. Perhaps at some point we will actually find a use for a stack like
// this.
;
explicit_group_end
: GE
{ curindex = yy.indexStack.shift(); }
;
node
: INDEX object
{ curindex = $1.slice(0,$1.length - 1); $$ = [ 'HAS', curindex, $2 ]; }
| object
{ if (typeof curindex === 'undefined') curindex = 'keyword'; $$ = [ 'HAS', curindex, $1 ]; }
;
phrase
: PHR
{ $$ = [ 'PHRASE', $1.substring(1, $1.length - 1) ]; }
;
object
: atomset
| phrase
;
atomset
: atomset atom
{ $1.push($2); $$ = $1; }
| atom
{ $$ = [ 'ATOM', $1 ]; }
;
atom
: WORD
{ $$ = $1; }
;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment