@top Program { statement* ProgramEnd } @precedence { else, call, times @left, plus @left, compare @left, and @left, or @left } statement { FunctionDecl | Assignment | IfStatement | ReturnStatement | Block | ExprStatement } ExprStatement { expression } FunctionDecl { discoverHowTo Identifier (with ArgumentList)? statement } ArgumentList { Identifier ("," Identifier)* } Assignment { expertsClaim Identifier toBe expression } IfStatement { whatIf expression statement (!else liesBang statement)? } ReturnStatement { shockingDevelopment expression } PrintStatement { youWontWantToMiss expression } InputStatement { latestNewsOn expression } Block { rumorHasIt statement* endOfStory } ParenBlock { "(" statement* ")" } FunctionCall { Identifier !call of ArgumentExpression ("," ArgumentExpression)* } ArgumentExpression { expression } expression { NumberLiteral | StringLiteral | BooleanLiteral | Identifier | FunctionCall | ParenBlock | PrintStatement | InputStatement | BinaryExpression } BinaryExpression { expression !times (times | dividedBy | modulo) expression | expression !plus (plus | minus) expression | expression !compare (isActually | beats | smallerThan) expression | expression !and and expression | expression !or or expression } ProgramEnd { pleaseLikeAndSubscribe } @skip { space | newline | Comment } @tokens { space { $[ \t]+ } newline { $[\n\r] } Comment { "#" (![\n\r] )* } identifierChar { $[A-Z_\-] | $[0-9] | "'" } word { ($[A-Z_\-] | "'") identifierChar* } @precedence { Comment, StringLiteral, NumberLiteral, BooleanLiteral, discoverHowTo, expertsClaim, latestNewsOn, pleaseLikeAndSubscribe, rumorHasIt, shockingDevelopment, whatIf, youWontWantToMiss, toBe, with, of, endOfStory, liesBang, isActually, dividedBy, smallerThan, and, or, plus, minus, times, modulo, beats, Identifier } Identifier { word } NumberLiteral { $[0-9]+ ("." $[0-9]+)? } StringLiteral { '"' (!["\\] | "\\" _)* '"' | "'" (!['\\] | "\\" _)* "'" } BooleanLiteral { "TOTALLY" space "RIGHT" | "COMPLETELY" space "WRONG" } discoverHowTo[@name="discoverHowTo"] { "DISCOVER" space "HOW" space "TO" } with[@name="with"] { "WITH" } of[@name="of"] { "OF" } expertsClaim[@name="expertsClaim"] { "EXPERTS" space "CLAIM" } toBe[@name="toBe"] { "TO" space "BE" } rumorHasIt[@name="rumorHasIt"] { "RUMOR" space "HAS" space "IT" } whatIf[@name="whatIf"] { "WHAT" space "IF" } liesBang[@name="liesBang"] { "LIES!" } endOfStory[@name="endOfStory"] { "END" space "OF" space "STORY" } shockingDevelopment[@name="shockingDevelopment"] { "SHOCKING" space "DEVELOPMENT" } youWontWantToMiss[@name="youWontWantToMiss"] { "YOU" space "WON'T" space "WANT" space "TO" space "MISS" } latestNewsOn[@name="latestNewsOn"] { "LATEST" space "NEWS" space "ON" } pleaseLikeAndSubscribe[@name="pleaseLikeAndSubscribe"] { "PLEASE" space "LIKE" space "AND" space "SUBSCRIBE" } isActually[@name="isActually"] { "IS" space "ACTUALLY" } and[@name="and"] { "AND" } or[@name="or"] { "OR" } plus[@name="plus"] { "PLUS" } minus[@name="minus"] { "MINUS" } times[@name="times"] { "TIMES" } dividedBy[@name="dividedBy"] { "DIVIDED" space "BY" } modulo[@name="modulo"] { "MODULO" } beats[@name="beats"] { "BEATS" } smallerThan[@name="smallerThan"] { "SMALLER" space "THAN" } "(" ")" "," } @detectDelim