`grep` but with PEG patterns. Define grammars (e.g. `digit`), functions for matching. No more regex syntax!

Overview

PEG

peggrep

Example file demo_file:

THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.
this line is the 1st lower case line in this file.
This Line Has All Its First Character Of The Word With Upper Case.

Two lines above this line is empty.
And this is the last line.

Match literals

$ peggrep "'this'" demo_file
this line is the 1st lower case line in this file.
Two lines above this line is empty.
And this is the last line.
  • 'this': match the literal string "this"

Match this.*empty

$ peggrep "'this' (!'empty' .)* 'empty'" demo_file
Two lines above this line is empty.
  • !'empty':
    • def: true if the current position is not followed by "empty"
    • ! does not consume any characters
  • .: consume one character unconditionally
  • (!'empty' .)*:
    • def: match any number of characters that are not followed by "empty"
    • when the position is at the e of "empty", the (!'empty' .)* exits
    • why not just .* 'empty':
      • * is greedy in PEG
      • .* will consume "empty" without exiting, so 'empty' has no chance to match
  • The final 'empty': match and consume the "empty"

To make life easier, we can make (!'empty' .)* 'empty' into a function:

  1. Write a grammar file:
    // grammar.peg
    until[str] <- (!str .)* str
                ;
  2. Run with the grammar file:
    $ peggrep -g grammar.peg "'this' until['empty']" demo_file
    Two lines above this line is empty.

Match digits

Steps:

  1. Write a grammar file:
    // grammar.peg
    digit <- '0' / '1' / '2' / '3' / '4' / '5' / '6' / '7' / '8' / '9'
           ;
  2. Run with the grammar file:
    $ peggrep -g grammar.peg "digit+" demo_file
    THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.
    this line is the 1st lower case line in this file.

Grammar file from environment variable

We don't want to write a grammar file every time we want to use it. We can use the environment variable PEGGREP_GRAMMAR to specify the grammar file:

$ export PEGGREP_GRAMMAR="/absolute/path/to/grammar.peg"
$ peggrep "'this' until['empty']" demo_file
Two lines above this line is empty.

Match all private functions

Steps:

  1. Write a grammar file:
    // grammar.peg
    space <- ' ' / '\t' / '\r' / '\n'
           ;
    _     <- space*
           ;
  2. Run:
    $ export PEGGREP_GRAMMAR="/absolute/path/to/grammar.peg"
    $ peggrep -^ "_ !'pub' 'fn'" src/*.rs
    • -^: match at the start of a line
    • _:
      • predefined in the grammar file
      • to match any number of spaces
You might also like...
Kalker (or
Kalker (or "kalk") is a calculator program/website that supports user-defined variables, functions, derivation, and integration

Kalker (or "kalk") is a calculator program/website that supports user-defined variables, functions, derivation, and integration. It runs on Windows, macOS, Linux, Android, and in web browsers (with WebAssembly).

The simplest way to de-Google your life and business: Inbox, Calendar, Files, Contacts & much more
The simplest way to de-Google your life and business: Inbox, Calendar, Files, Contacts & much more

Bloom The all-in-one private workspace Try it for free! You no longer trust tech monopolies with your data? You are done with your privacy invaded by

Milho (corn in portuguese) is a toy dialect of Lisp written as a way to learn more about compilers

Milho (corn in portuguese) is a toy dialect of Lisp written as a way to learn more about compilers. There are implementations in rust and go

A Discord bot focused on addressing the inherent problems with Discord, to allow a more socialist/anarchist organization of servers.

ACABot A Discord bot focused on addressing the inherent problems with Discord, to allow a more socialist/anarchist organization of servers (or "guilds

Rust bindings for libjuice. Look at datachannel-rs if you need more batteries.

Rust bindings for libjuice. Look at datachannel-rs if you need more batteries.

Utility to quickly setup Starcraft Broodwar matches between 2 or more bots

BWAIShotgun Utility to quickly setup Starcraft Broodwar matches between 2 or more bots Be aware that all bots will be executed directly, without any l

An abstraction build on top of discord-rich-presence that makes possible to use it in a more declarative way

Declarative Discord Rich Presence This library is an abstraction build on top of discord-rich-presence crate that allows you to use it in a more decla

CFD is a tool that allows you to check one or more domains to see if they are protected by CloudFlare or not.
CFD is a tool that allows you to check one or more domains to see if they are protected by CloudFlare or not.

CFD is a tool that allows you to check one or more domains to see if they are protected by CloudFlare or not. The check is carried out based on five criteria: 3 headers in the HTTP response, IP, and SSL certificate issuer. The check result can be displayed on the screen or saved to a file.

A Simple, But amazing telegram bot, Made using the Rust language!

Telegram bot in Rust A fun Telegram bot made using Rust language.

Owner
IchHabeKeineNamen
鄙人只关注代码维护性,时间都用在代码上,没时间浪费去背八股文,不刷算法题,卡我算法算你赢。 BanycGitHub at outlook.com
IchHabeKeineNamen
Define safe interfaces to MMIO and CPU registers with ease

regi regi lets you define safe interfaces to MMIO and CPU registers with ease. License Licensed under either of Apache License, Version 2.0 or MIT lic

Valentin B. 2 Feb 10, 2022
Const equivalents of many [`bytemuck`] functions, and a few additional const functions.

Const equivalents of many bytemuck functions, and a few additional const functions. constmuck uses bytemuck's traits, so any type that implements thos

null 6 Nov 4, 2021
Rust Keeper bots that run various functions, from liquidations, to orderbook cranks, and more.

The zo-keeper (pronounced "zoo keeper") repository runs large scale instructions that secure the 01 network, and allow it to operate in a fully decentralized manner.

Zero One Global Foundation 61 Dec 16, 2022
`Debug` in rust, but only supports valid rust syntax and outputs nicely formatted using pretty-please

dbg-pls A Debug-like trait for rust that outputs properly formatted code Showcase Take the following code: let code = r#" [ "Hello, World!

Conrad Ludgate 12 Dec 22, 2022
a simple compiled language i made in rust. it uses intermediate representation (IR) instead of an abstract syntax tree (AST).

a simple compiled language i made in rust. it uses intermediate representation (IR) instead of an abstract syntax tree (AST).

null 4 Oct 3, 2022
Analogous, indented syntax for the Rust programming language.

Note: After experimenting with this in the wild, I have found representing keywords as symbols to be far less readable in large codebases. Additionall

null 42 Oct 2, 2021
tr-lang is a language that aims to bring programming language syntax closer to Turkish.

tr-lang Made with ❤️ in ???? tr-lang is a language that aims to bring programming language syntax closer to Turkish. tr-lang is a stack based language

Kerem Göksu 10 Apr 2, 2022
A syntax exploration of eventually stable Rust Iterator items

Rust Iterator Items: a syntax exploration This crate is a thin wrapper around the unstable generator feature, allowing users to create new items that

Esteban Kuber 28 Sep 1, 2022
Rust macro to use a match-like syntax as a elegant alternative to nesting if-else statement

cond Rust macro to use a match-like syntax as an elegant alternative to many if-else statements. I got the idea from empty Go switch statements. I tho

CheckM4te 3 Nov 23, 2023
A Rust proc-macro crate which derives functions to compile and parse back enums and structs to and from a bytecode representation

Bytecode A simple way to derive bytecode for you Enums and Structs. What is this This is a crate that provides a proc macro which will derive bytecode

null 4 Sep 3, 2022