@@ignorecase :: True
@@parseinfo :: True

be = "am" |
	"are" |
	"art" |
	"be" |
	"is";

article = "a" |
	"an" |
	"the";

first_person = "I" |
	"me";

first_person_reflexive = "myself";

first_person_possessive = "mine" | "my";

second_person = "thee" |
	"thou" |
	"you";

second_person_reflexive = "thyself" | "yourself";

second_person_possessive = "thine" | "thy" | "your";

third_person_possessive = "his" | "her" | "its" | "their";

possessive = first_person_possessive | second_person_possessive | third_person_possessive;

positive_comparative = comparison:("better" | "bigger" | "fresher" | "friendlier" | "nicer" | "jollier" | "more" positive_adjective) "than";

negative_comparative = comparison:("punier" |
	"smaller" |
	"worse" | "more" negative_adjective) "than";

negative_adjective = "bad" |
	"cowardly" |
	"cursed" |
	"damned" |
	"dirty" |
	"disgusting" |
	"distasteful" |
	"dusty" |
	"evil" |
	"fat-kidneyed" |
	"fatherless" |
	"fat" |
	"foul" |
	"hairy" |
	"half-witted" |
	"horrible" |
	"horrid" |
	"infected" |
	"lying" |
	"miserable" |
	"misused" |
	"oozing" |
	"rotten" |
	"rotten" |
	"smelly" |
	"snotty" |
	"sorry" |
	"stinking" |
	"stuffed" |
	"stupid" |
	"vile" |
	"villainous" |
	"worried";

neutral_adjective = "big" |
	"black" |
	"blue" |
	"bluest" |
	"bottomless" |
	"furry" |
	"green" |
	"hard" |
	"huge" |
	"large" |
	"little" |
	"normal" |
	"old" |
	"purple" |
	"red" |
	"rural" |
	"small" |
	"tiny" |
	"white" |
	"yellow";

positive_adjective = "amazing" |
	"beautiful" |
	"blossoming" |
	"bold" |
	"brave" |
	"charming" |
	"clearest" |
	"cunning" |
	"cute" |
	"delicious" |
	"embroidered" |
	"fair" |
	"fine" |
	"gentle" |
	"golden" |
	"good" |
	"handsome" |
	"happy" |
	"healthy" |
	"honest" |
	"lovely" |
	"loving" |
	"mighty" |
	"noble" |
	"peaceful" |
	"pretty" |
	"prompt" |
	"proud" |
	"reddest" |
	"rich" |
	"smooth" |
	"sunny" |
	"sweet" |
	"sweetest" |
	"trustworthy" |
	"warm";

negative_noun = "Hell" |
	"Microsoft" |
	"bastard" |
	"beggar" |
	"blister" |
	"codpiece" |
	"coward" |
	"curse" |
	"death" |
	"devil" |
	"draught" |
	"famine" |
	"flirt-gill" |
	"goat" |
	"hate" |
	"hog" |
	"hound" |
	"leech" |
	"lie" |
	"pig" |
	"plague" |
	"starvation" |
	"toad" |
	"war" |
	"wolf";

neutral_noun = "animal" |
	"aunt" |
	"brother" |
	"cat" |
	"chihuahua" |
	"cousin" |
	"cow" |
	"daughter" |
	"door" |
	"face" |
	"father" |
	"fellow" |
	"granddaughter" |
	"grandfather" |
	"grandmother" |
	"grandson" |
	"hair" |
	"hamster" |
	"horse" |
	"lamp" |
	"lantern" |
	"mistletoe" |
	"moon" |
	"morning" |
	"mother" |
	"nephew" |
	"niece" |
	"nose" |
	"purse" |
	"road" |
	"roman" |
	"sister" |
	"sky" |
	"son" |
	"squirrel" |
	"stone" "wall" |
	"thing" |
	"town" |
	"tree" |
	"uncle" |
	"wind";

positive_noun = "Heaven" |
	"King" |
	"Lord" |
	"angel" |
	"flower" |
	"happiness" |
	"joy" |
	"plum" |
	"summer's" "day" |
	"hero" |
	"rose" |
	"kingdom" |
	"pony";

character = "Achilles" |
	"Adonis" |
	"Adriana" |
	"Aegeon" |
	"Aemilia" |
	"Agamemnon" |
	"Agrippa" |
	"Ajax" |
	"Alonso" |
	"Andromache" |
	"Angelo" |
	"Antiochus" |
	"Antonio" |
	"Arthur" |
	"Autolycus" |
	"Balthazar" |
	"Banquo" |
	"Beatrice" |
	"Benedick" |
	"Benvolio" |
	"Bianca" |
	"Brabantio" |
	"Brutus" |
	"Capulet" |
	"Cassandra" |
	"Cassius" |
	"Christopher" "Sly" |
	"Cicero" |
	"Claudio" |
	"Claudius" |
	"Cleopatra" |
	"Cordelia" |
	"Cornelius" |
	"Cressida" |
	"Cymberline" |
	"Demetrius" |
	"Desdemona" |
	"Dionyza" |
	"Doctor" "Caius" |
	"Dogberry" |
	"Don" "John" |
	"Don" "Pedro" |
	"Donalbain" |
	"Dorcas" |
	"Duncan" |
	"Egeus" |
	"Emilia" |
	"Escalus" |
	"Falstaff" |
	"Fenton" |
	"Ferdinand" |
	"Ford" |
	"Fortinbras" |
	"Francisca" |
	"Friar" "John" |
	"Friar" "Laurence" |
	"Gertrude" |
	"Goneril" |
	"Hamlet" |
	"Hecate" |
	"Hector" |
	"Helen" |
	"Helena" |
	"Hermia" |
	"Hermonie" |
	"Hippolyta" |
	"Horatio" |
	"Imogen" |
	"Isabella" |
	"John" "of" "Gaunt" |
	"John" "of" "Lancaster" |
	"Julia" |
	"Juliet" |
	"Julius" "Caesar" |
	"King" "Henry" |
	"King" "John" |
	"King" "Lear" |
	"King" "Richard" |
	"Lady" "Capulet" |
	"Lady" "Macbeth" |
	"Lady" "Macduff" |
	"Lady" "Montague" |
	"Lennox" |
	"Leonato" |
	"Luciana" |
	"Lucio" |
	"Lychorida" |
	"Lysander" |
	"Macbeth" |
	"Macduff" |
	"Malcolm" |
	"Mariana" |
	"Mark" "Antony" |
	"Mercutio" |
	"Miranda" |
	"Mistress" "Ford" |
	"Mistress" "Overdone" |
	"Mistress" "Page" |
	"Montague" |
	"Mopsa" |
	"Oberon" |
	"Octavia" |
	"Octavius" "Caesar" |
	"Olivia" |
	"Ophelia" |
	"Orlando" |
	"Orsino" |
	"Othello" |
	"Page" |
	"Pantino" |
	"Paris" |
	"Pericles" |
	"Pinch" |
	"Polonius" |
	"Pompeius" |
	"Portia" |
	"Priam" |
	"Prince" "Henry" |
	"Prospero" |
	"Proteus" |
	"Publius" |
	"Puck" |
	"Queen" "Elinor" |
	"Regan" |
	"Robin" |
	"Romeo" |
	"Rosalind" |
	"Sebastian" |
	"Shallow" |
	"Shylock" |
	"Slender" |
	"Solinus" |
	"Stephano" |
	"Thaisa" |
	"The" "Abbot" "of" "Westminster" |
	"The" "Apothecary" |
	"The" "Archbishop" "of" "Canterbury" |
	"The" "Duke" "of" "Milan" |
	"The" "Duke" "of" "Venice" |
	"The" "Ghost" |
	"Theseus" |
	"Thurio" |
	"Timon" |
	"Titania" |
	"Titus" |
	"Troilus" |
	"Tybalt" |
	"Ulysses" |
	"Valentine" |
	"Venus" |
	"Vincentio" |
	"Viola";

nothing = nothing_word:("nothing" | "zero");

positive_or_neutral_adjective = positive_adjective | neutral_adjective;

positive_or_neutral_noun = positive_noun | neutral_noun;

neutral_comparative = "as" comparison:(negative_adjective | positive_or_neutral_adjective) "as";

negative_noun_phrase = [article | possessive] adjectives:{(negative_adjective | neutral_adjective)}* noun:negative_noun;

positive_noun_phrase = [article | possessive] adjectives:{positive_or_neutral_adjective}* noun:positive_or_neutral_noun;

noun_phrase = negative_noun_phrase |
	positive_noun_phrase;

first_person_value = first_person_word:(first_person | first_person_reflexive);

second_person_value = second_person_word:(second_person | second_person_reflexive);

character_name = name:character;

value = expression |
	first_person_value |
	second_person_value |
	noun_phrase |
	character_name |
	nothing;

binary_operation = "the" "difference" "between" |
	"the" "product" "of" |
	"the" "quotient" "between" |
	"the" "remainder" "of" "the" "quotient" "between" |
	"the" "sum" "of";

binary_expression = operation:binary_operation first_value:value 'and' second_value:value;

unary_operation = "the" "cube" "of" |
	"the" "factorial" "of" |
	"the" "square" "of" |
	"the" "square" "root" "of" |
	"twice";

unary_expression = operation:unary_operation value:value;

expression = binary_expression | unary_expression;

negative_if = if:("If" "not" ",");

positive_if = if:("If" "so" ",");

question = be first_value:value comparative:(positive_comparative | neutral_comparative | negative_comparative) second_value:value "?";

assignment = second_person [be] ["as" [(positive_or_neutral_adjective | negative_adjective) "as"]] value:value ("!" | ".");

let_us = "Let" "us" | "We" "shall" | "We" "must";

proceed_to = "proceed" "to" | "return" "to";

roman_numeral = value:?/(?i)M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})/?;

goto = let_us proceed_to "scene" destination:roman_numeral ("!" | ".");

output = (output_number:("open" second_person_possessive "heart") | output_char:("speak" second_person_possessive "mind")) ("!" | ".");

input = (input_number:("listen" "to" second_person_possessive "heart") | input_char:("open" second_person_possessive "mind")) ("!" | ".");

push = "Remember" value:value ("!" | ".");

pop = "Recall" recall_string:text_before_punctuation ("!" | ".");

sentence = condition:[negative_if | positive_if] operation:(question | assignment | goto | output | input | push | pop);

line_contents = @+:sentence {?"\s*" @+:sentence};

line = character:character ":" contents:line_contents;

character_list = @+:character {"," @+:character}* "and" @+:character | @+:character;

breakpoint = dummy:("[" "A" "pause" "]");

entrance = "[" "Enter" characters:character_list "]";

exit = "[" "Exit" character:character "]";

exeunt = "[" action:"Exeunt" [characters:character_list] "]";

event = line | breakpoint | entrance | exit | exeunt;

repl_input =  !(character ":") display_character:character $ | !(character ":" /.*\./) [expression_character:character ":"] value:value $ | event:event $ | sentences:({sentence}+) $;

text_before_punctuation = ?/[^!\.]*/?;

scene = "Scene" ?"\s*" number:roman_numeral ":" name:text_before_punctuation ("!" | ".") events:({event}*);

act = "Act" ?"\s*" number:roman_numeral ":" name:text_before_punctuation ("!" | ".") scenes:({scene}*);

dramatis_persona = character:character ',' text_before_punctuation ("!" | ".");

dramatis_personae = {?"\s*" @+:dramatis_persona}*;

play = title:text_before_punctuation ("!" | ".") dramatis_personae:dramatis_personae acts:({act}*) $;
