shakespeare-parrot / src / parser / grammar.pg

grammar z2::Grammar is PCT::Grammar;

rule TOP {
  <shebang>?
  <title>
  <chardef>*
  <act>*
  {*}
}

rule shebang {
  '#!' \N*
}

rule title {
    <description> <end> 
}
rule scene {
  'scene' <roman> ':' <description> <end>
  <events>*
  {*}
}
rule act {
  'act' <roman> ':' <description> <end>
  {*} #= open
  <scene>* 
  {*} #= close
}

rule events {
  | <line> {*}   #= line
  | <move> {*}  #= move
}

rule chardef {
  <character> ',' <description> <end> {*}
}
rule line {
  <character> ':' [<sentence> <end>]+  {*}
}
rule charlist {
  <character>? ['and' <character>]*
}
rule sentence {
  | <tap> {*}  #= tap
  | <plan> {*} #= plan
  | <memorize> {*} #= memorize
  | <branch>        {*} #= branch
  | <question> {*} #= question
  | <test>     {*} #= test
  | <io>          {*} #= io
  | <assignment>  {*} #= assignment
  | <value>       {*} #= value
  | <recall> {*} #= recall
}
token end { <[.!?]> }

rule tap {
  'proove' <value> {*}
}

rule memorize {
  'remember' <value> {*}
}

rule recall {
  'recall' <-end>* {*}
}

rule plan {
  'plan' <value> {*}
}

rule io {
  |'open' <second_person_possessive> 'heart' {*} #= open_heart
  |'speak' <second_person_possessive> 'mind' {*} #= speak_mind
  |'listen' 'to' <second_person_possessive> 'heart' {*} #= listen_heart
  |'open' <second_person_possessive> 'mind' {*} #= open_mind
}

rule assignment {
  |<second_person> <be> 'as' <adjective> 'as' <value> {*}
  |<second_person> <be>? <value> {*}
}

rule branch {
  [ 'let' 'us' | 'we' [ 'shall' | 'must' ] ]  [ 'return' | 'proceed' ] 'to' 'scene' <roman> {*}
}

rule question {
  <be> <value> <comparison> <value>{*}
}

rule comparison {
  | ['more' <negative_adjective> 
    |'less' <positive_adjective>
    |<negative_comparative>] 'than' {*} #= worse
  | ['more' <positive_adjective>
    |'less' <negative_adjective> 
    |<positive_comparative>] 'than' {*} #= better
  | 'as' <adjective> 'as' {*} #= equal
}
rule test {
  | 'if so,' <sentence>  {*} #= if
  | 'if not,' <sentence> {*} #= unless
}
rule computation {
  <article>?
  [
  |<binary> {*} #= binary
  |<unary> {*} #= unary
  ]
}

rule binary {
  |'remainder' 'of' 'the' 'quotient' 'between' <value> 'and' <value> {*} #= mod
  |'difference' 'between' <value> 'and' <value> {*} #= sub
  |'sum' 'of' <value> 'and' <value> {*} #= add
  |'product' 'of' <value> 'and' <value> {*} #= mul
  |'quotient' 'between' <value> 'and' <value> {*} #= div
}

rule unary {
  |'factorial' 'of' <value> {*} #= fact
  |'square' 'of' <value> {*} #= square
  |'square root' 'of' <value> {*} #= sqrt
  |'cube' 'of' <value> {*} #= cube
  |'twice' <value> {*} #= dup
}

rule value {
  |<reference> {*}   #= reference
  |<immediate> {*}   #= immediate
  |<computation> {*} #= computation
}

rule immediate {
  <article>? [<adjective> ]* <noun> {*} 
}

token noun {
  |<positive_noun>
  |<negative_noun>
  |<neutral_noun> 
  |<nothing>
}

token reference {
  |<second_person_reflexive> {*} #= you_ref
  |<second_person> {*} #= you_ref
  |<first_person> {*} #= self_ref
  |<first_person_reflexive> {*} #= self_ref
  |<character> {*} #= named_ref
}

token adjective {
  |<positive_adjective>
  |<neutral_adjective>
  |<negative_adjective>
  |<first_person_possessive>
  |<second_person_possessive>
  |<third_person_possessive>
}

token roman {
  ['iii' | 'ii' |  'iv' | 'i' | 'vii' | 'vi' | 'v' ]
}

rule move {
  '['
    [
    |'enter' <character> ['and' <character>]* {*} #= enter
    # nqp does not have a flatten function, this enforces
    # the iterability of a single match 
    |'exit'  <character>**{1} {*} #= exit
    |'exeunt' <character> ['and' <character>]+ {*} #= exit
    |'exeunt' {*} #= exeunt
    ]
  ']'
}

token description {
  <-end>*
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.