# -* text -*- ## PE grammar for the grammar specification language accepted by the ## LEMON parser generator. ## Questions: ## Are directives always at the beginning of a line ? ## Or can they start within a line ? ## The ifdef/ifndef/endif directives are not documented. ## Nor are the cmdline options PEG pg::peg::lemon (LemonGrammar) LemonGrammar <- SPACE Statement + EOF; Statement <- ( Directive / Rule ) SPACE; Rule <- Identifier Label? ASSIGN Definition DOT Precedence? Codeblock? ; Definition <- (Identifier Label?)* ; Label <- LPAREN Identifier RPAREN; Precedence <- LBRACKET Identifier RBRACKET; Directive <- DINTRO ( Code / DefaultDestructor / DefaultType / Destructor / ExtraArgument / Include / Left / Name / Nonassoc / ParseAccept / ParseFailure / Right / StackOverflow / Stacksize / StartSymbol / SyntaxError / TokenDestructor / TokenPrefix / TokenType / Type / Fallback ); Code <- DCODE Codeblock; DefaultDestructor <- DDEFDEST Identifier Codeblock; DefaultType <- DDEFTYPE Codeblock; Destructor <- DDEST Identifier Codeblock; ExtraArgument <- DEXTRA Codeblock; Include <- DINCL Codeblock; Left <- DLEFT Identifier+ DOT; Name <- DNAME Identifier ; Nonassoc <- DNON Identifier+ DOT; ParseAccept <- DPACC Codeblock; ParseFailure <- DPFAIL Codeblock; Right <- DRIGHT Identifier+ DOT; StackOverflow <- DSTKOVER Codeblock; Stacksize <- DSTKSZ NaturalNumber; StartSymbol <- DSTART Identifier; SyntaxError <- DSYNERR Codeblock; TokenDestructor <- DTOKDEST Identifier Codeblock; TokenPrefix <- DTOKPFX Identifier; TokenType <- DTOKTYPE Codeblock; Type <- DTYPE Identifier Codeblock; Fallback <- DFALLBK Identifier+ DOT; # Lexical layer match: Codeblock <- LBRACE ( Codeblock / C_COMMENT / Cplusplus_COMMENT / (!RBRACE .) )* RBRACE ; Identifier <- Ident SPACE; match: Ident <- (/'_') (/'_')*; NaturalNumber <- NatNum SPACE; match: NatNum <- [0-9]+; void: ASSIGN <- '::=' SPACE; void: DOT <- '.' SPACE; void: LPAREN <- '(' SPACE; void: RPAREN <- ')' SPACE; void: LBRACKET <- '[' SPACE; void: RBRACKET <- ']' SPACE; void: LBRACE <- '{'; void: RBRACE <- '}'; void: DINTRO <- '%'; void: DCODE <- 'code' SPACE; void: DDEFDEST <- 'default_destructor' SPACE; void: DDEFTYPE <- 'default_type' SPACE; void: DDEST <- 'destructor' SPACE; void: DEXTRA <- 'extra_argument' SPACE; void: DINCL <- 'include' SPACE; void: DLEFT <- 'left' SPACE; void: DNAME <- 'name' SPACE; void: DNON <- 'nonassoc' SPACE; void: DPACC <- 'parse_accept' SPACE; void: DPFAIL <- 'parse_failure' SPACE; void: DRIGHT <- 'right' SPACE; void: DSTKOVER <- 'stack_overflow' SPACE; void: DSTKSZ <- 'stack_size' SPACE; void: DSTART <- 'start_symbol' SPACE; void: DSYNERR <- 'syntax_error' SPACE; void: DTOKDEST <- 'token_destructor' SPACE; void: DTOKPFX <- 'token_prefix' SPACE; void: DTOKTYPE <- 'token_type' SPACE; void: DTYPE <- 'type' SPACE; void: DFALLBK <- 'fallback' SPACE; # These have % in their definition because they # are not part of the regular directives. void: DIFDEF <- '%ifdef' SPACE; void: DIFNDEF <- '%ifndef' SPACE; void: DENDIF <- '%endif' SPACE; # Directives we do not really know about. They are in the SQLite # parse.y file, but are not documented for LEMON. We treat them as # whitespace for now, see below. Ifdef <- DIFDEF Identifier; Ifndef <- DIFNDEF Identifier; Endif <- DENDIF; # Whitespace void: SPACE <- ( [ \t\n\r] / C_COMMENT / Cplusplus_COMMENT / Ifndef / Ifdef / Endif )*; C_COMMENT <- CCOM_OPEN (!CCOM_CLOSE .)* CCOM_CLOSE; CCOM_OPEN <- '/*'; CCOM_CLOSE <- '*/'; Cplusplus_COMMENT <- '//' (!EOL .)* EOL; EOL <- '\r\n' / '\r' / '\n'; EOF <- !.; END;