Skip to content

Instantly share code, notes, and snippets.

@Varriount
Last active May 26, 2019 17:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Varriount/103aec43b11e1689fef41fceb8c7187c to your computer and use it in GitHub Desktop.
Save Varriount/103aec43b11e1689fef41fceb8c7187c to your computer and use it in GitHub Desktop.
import npeg
let parser = peg "COMMANDS":
COMMANDS <- COMMAND * *( SEPERATOR_SYM * COMMAND )
COMMAND <- +(
SPACES |
REDIRECT_SYM |
COMMAND_SUB |
VARIABLE_SUB |
DQ_STRING_LIT |
WORD_LIT
)
# Words
WORD_LIT <- >+( WORD_CHAR - SUB_MARKER_SYM ) : echo "WORD_LIT: ", $1
WORD_CHAR <- Alpha | Digit
UTF8 <- {0..244}
# Double Quoted Strings
DQ_STRING_LIT <-
DQ_STRING_START *
DQ_STRING_DATA *
DQ_STRING_END
DQ_STRING_START <- DQ_STRING_START_SYM : echo "DQ_STRING_START"
DQ_STRING_END <- DQ_STRING_END_SYM | E_MISSING_QUOTE : echo "DQ_STRING_END"
DQ_STRING_DATA <- *(
COMMAND_SUB |
VARIABLE_SUB |
DQ_STRING_ESCAPE |
DQ_STRING_CHARS
)
DQ_STRING_CHARS <- >+DQ_STRING_CHAR : echo "DQ_STRING_CHARS: ", $1
DQ_STRING_CHAR <- >(UTF8 - SUB_MARKER_SYM - DQ_STRING_ESCAPE - '"' )
DQ_STRING_ESCAPE <- '\\' * ( SUB_ESCAPE | UTF8_ESCAPE | CHAR_ESCAPE | '"')
# Single Quoted Strings
SQ_STRING_LIT <-
SQ_STRING_START *
SQ_STRING_DATA *
SQ_STRING_END
SQ_STRING_START <- SQ_STRING_START_SYM : echo "SQ_STRING_START"
SQ_STRING_END <- SQ_STRING_END_SYM | E_MISSING_QUOTE : echo "SQ_STRING_END"
SQ_STRING_DATA <- *(
COMMAND_SUB |
VARIABLE_SUB |
SQ_STRING_ESCAPE |
SQ_STRING_CHARS
)
SQ_STRING_CHARS <- >+SQ_STRING_CHAR : echo "SQ_STRING_CHARS: ", $1
SQ_STRING_CHAR <- >(UTF8 - SUB_MARKER_SYM - SQ_STRING_ESCAPE - '\'' )
SQ_STRING_ESCAPE <- '\\' * ( SUB_ESCAPE | UTF8_ESCAPE | CHAR_ESCAPE | '\'')
# Escapes
UTF8_ESCAPE <- >('u' * Xdigit[4]) : echo "UTF8_ESCAPE: ", $1
SUB_ESCAPE <- >SUB_MARKER_SYM : echo "SUB_ESCAPE: ", $1
CHAR_ESCAPE <- >{ '\\', 'b', 'f', 'n', 'r', 't' } : echo "CHAR_ESCAPE: ", $1
# Command Substitutions
COMMAND_SUB <-
COMMAND_SUB_START *
COMMAND_SUB_DATA *
COMMAND_SUB_END
COMMAND_SUB_START <- "$(" : echo "COMMAND_SUB_START"
COMMAND_SUB_END <- ")" | E_MISSING_CBRACE : echo "COMMAND_SUB_END"
COMMAND_SUB_DATA <- COMMAND | E_INVALID_SUB
# Command Substitutions
VARIABLE_SUB <-
VARIABLE_SUB_START *
VARIABLE_SUB_DATA *
VARIABLE_SUB_END
VARIABLE_SUB_START <- "${" : echo "VARIABLE_SUB_START"
VARIABLE_SUB_END <- "}" | E_MISSING_PAREN : echo "VARIABLE_SUB_END"
VARIABLE_SUB_DATA <- WORD_LIT | E_INVALID_SUB
# Symbols
SUB_MARKER_SYM <- (
COMMAND_SUB_START_SYM |
COMMAND_SUB_END_SYM |
VARIABLE_SUB_START_SYM |
VARIABLE_SUB_END_SYM
)
DQ_STRING_START_SYM <- '"'
DQ_STRING_END_SYM <- '"'
SQ_STRING_START_SYM <- '\''
SQ_STRING_END_SYM <- '\''
COMMAND_SUB_START_SYM <- "$("
COMMAND_SUB_END_SYM <- ")"
VARIABLE_SUB_START_SYM <- "${"
VARIABLE_SUB_END_SYM <- "}"
SEPERATOR_SYM <- ( "&&" | "||" | ";")
REDIRECT_SYM <- ( ">>" | "!>" | "!>>" | ">" | "<")
SPACES <- +Space
# Errors
E_MISSING_QUOTE <- E"Umatched quotation"
E_MISSING_CBRACE <- E"Missing curly brace"
E_MISSING_PAREN <- E"Missing parenthesis"
E_INVALID_SUB <- E"Invalid substitution"
echo parser.match("""echo hello"jj$($("world"))\" >""").captures
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment