grammar lolcode::Grammar is PCT::Grammar;
rule TOP { ['HAI' <version> <.statement_terminator>]? <block> ['KTHXBYE' <.statement_terminator>]? [ $ || <panic: 'Syntax error'> ] {*} }
token version { \d+ [ '.' \d+ ]? }
rule statement { | <declare> {*} #= declare | <assign> {*} #= assign | <function> {*} #= function | <ifthen> {*} #= ifthen | <switch> {*} #= switch | <expression> {*} #= expression }
token statement_terminator { [ ',' | \n+ | $ ] }
rule declare { 'I' 'HAS' 'A' <scope>? <variable> [ 'ITZ' <expression> ]? {*} }
token scope { | 'FARAWAY' | 'NEARBY' }
rule assign { <variable> 'R' <expression> {*} }
rule function { # $<parameters> is only getting the first parameter, not all of them # like I'd expect... 'HOW' 'DUZ' 'I' <variable> ['YR' $<parameters>=<variable> [ 'AN' 'YR' $<parameters>=<variable>]* ]?<.statement_terminator> {*} #= params <block> 'IF' 'U' 'SAY' 'SO' {*} #= block }
rule ifthen { <expression> <.statement_terminator> 'O' 'RLY?' <.statement_terminator> 'YA' 'RLY' <.statement_terminator> <block> [ 'MEBBE' <expression> <.statement_terminator> <block> ]* [ 'NO' 'WAI' <.statement_terminator> $<else>=<block> ]? 'OIC' {*} }
rule switch { 'WTF?' <.statement_terminator> [ 'OMG' <value> <.statement_terminator> <block> ]+ [ 'OMGWTF' <.statement_terminator> <else=block> ]? 'OIC' {*} }
rule block { {*} #= open [<statement> <.statement_terminator>]* {*} #= close }
rule parameters { 'YR' <identifier> [ 'AN' 'YR' <identifier> ]* }
rule expression { [ | $<tokens>=<operator> | $<tokens>=<variable> | $<tokens>=<value> | 'AN' | $<tokens>='MKAY' ]+ {*} }
token value { | <float> {*} #= float | <integer> {*} #= integer | <boolean> {*} #= boolean | <quote> {*} #= quote | <bang> {*} #= bang }
token bang { '!' {*} }
token operator { $<identifier>=(<.identifier> <.ws> 'OF'|'BOTH SAEM') {*} } token variable { <identifier> {*} }
token identifier { <!keyword> <[a..zA..Z]> \w* }
# RT #46213 : Because PGE doesn't yet know how to do longest token matching, # order all tokens in reverse alpha order to avoid a parsing bug. token keyword { [ 'YR' | 'YA' | 'WTF?' | 'WIN' | 'WAI' | 'U' | 'SO' | 'SAY' | 'RLY?' | 'RLY' | 'R' | 'OMGWTF' | 'OMG' | 'OIC' | 'OF' | 'O' | 'NO' | 'MKAY' | 'MEBBE' | 'KTHXBYE' | 'ITZ' | 'IF' | 'I' | 'HOW' | 'HAS' | 'GTFO' | 'FOUND' | 'FARAWAY' | 'FAIL' | 'AN' | 'A' ] >> }
token integer { '-'? \d+ {*} }
token float { '-'? \d+ '.' \d+ {*} }
rule boolean { [ 'WIN' | 'FAIL' ] {*} }
rule quote { [ <.before '"'> <yarn_literal> ] {*} }
token ws { <!ww> [ | ^^ \h* BTW \h \N* \n+ | ^^ \h* OBTW .*? ^^ \h* TLDR \n+ | \h+ ]* }