Added tests/tutorial

This commit is contained in:
Bruce Hill 2021-08-28 14:26:32 -07:00
parent 9db5e91781
commit 16bf40bd64
78 changed files with 313 additions and 3 deletions

View File

@ -43,8 +43,15 @@ clean:
rm -f $(NAME) $(OBJFILES)
test: $(NAME)
./$(NAME) Comment -r '[@0]'
./$(NAME) -g ./grammars/bp.bp -p Grammar ./grammars/bp.bp
./$(NAME) Comment -r '[@0]' >/dev/null
./$(NAME) -g ./grammars/bp.bp -p Grammar ./grammars/bp.bp >/dev/null
for test in tests/*.sh; do \
sh "$$test" <"$${test/.sh/.in}" | diff -q - "$${test/.sh/.out}" ||\
sh "$$test" <"$${test/.sh/.in}" | diff -y --color=always - "$${test/.sh/.out}"; \
done
tutorial:
./tutorial.sh
leaktest: bp
valgrind --leak-check=full ./bp -l -g ./grammars/bp.bp -p Grammar ./grammars/bp.bp
@ -74,4 +81,4 @@ uninstall:
[ "$$confirm" != n ] && rm -rf ~/.config/$(NAME); \
fi
.PHONY: all clean install uninstall leaktest splint test
.PHONY: all clean install uninstall leaktest splint test tutorial

View File

@ -79,6 +79,11 @@ Pattern | Meaning
See `man ./bp.1` for more details.
## Tutorial
Run `make tutorial` to run through the tutorial. It walks through some basic pattern matching.
## Grammar Files
BP comes packaged with some pattern definitions that can be useful when parsing

5
tests/1-literal.in Normal file
View File

@ -0,0 +1,5 @@
xxx
foo
baz
xxfooxx
zzz

2
tests/1-literal.out Normal file
View File

@ -0,0 +1,2 @@
foo
xxfooxx

3
tests/1-literal.sh Normal file
View File

@ -0,0 +1,3 @@
# Use double quotation marks to match literal strings
# Example: bp -p '"baz"'
bp -p '"foo"'

5
tests/10-words.in Normal file
View File

@ -0,0 +1,5 @@
foobar
foo
bazfoo
xxfooxx
one foo two

2
tests/10-words.out Normal file
View File

@ -0,0 +1,2 @@
foo
one foo two

3
tests/10-words.sh Normal file
View File

@ -0,0 +1,3 @@
# The | operator matches word edges
# Example: bp -p '|"baz"|' matches the word "baz"
bp '\|foo\|'

View File

@ -0,0 +1,4 @@
foo
bar
xxx
yyy

View File

@ -0,0 +1,2 @@
foo
bar

View File

@ -0,0 +1,5 @@
# The ordered choice operator (/) picks the first choice that matches
# Example: bp -p '"cabaret"/"cab"' matches either "cabaret" or "cab"
# Note: if a match occurs, the options to the right will *never* be attempted,
# so bp -p '"cab"/"cabaret"' will always match "cab" instead of "cabaret"
bp -p '"foo" / "bar"'

5
tests/12-star.in Normal file
View File

@ -0,0 +1,5 @@
()
(x)
(xxxxxx)
(y)
nope

3
tests/12-star.out Normal file
View File

@ -0,0 +1,3 @@
()
(x)
(xxxxxx)

3
tests/12-star.sh Normal file
View File

@ -0,0 +1,3 @@
# The star (*) prefix operator matches zero or more repetitions
# Example: bp -p '"Ha" *"ha"' will match "Ha", "Haha", "Hahaha", etc.
bp -p '`( *`x `)'

5
tests/13-plus.in Normal file
View File

@ -0,0 +1,5 @@
(x)
(xxxxxx)
(y)
()
nope

2
tests/13-plus.out Normal file
View File

@ -0,0 +1,2 @@
(x)
(xxxxxx)

3
tests/13-plus.sh Normal file
View File

@ -0,0 +1,3 @@
# The plus (+) prefix operator matches one or more of a pattern
# Example: bp -p '"l" +"ol"' will match "lol", "lolol", "lololol", etc.
bp -p '`( +`x `)'

8
tests/14-repeat-sep.in Normal file
View File

@ -0,0 +1,8 @@
foo(1)
foo(1,2,3,4)
foo(23,34,56)
foo(xxx)
foo(,,1,,)
xxx
,,,
1,2,3

3
tests/14-repeat-sep.out Normal file
View File

@ -0,0 +1,3 @@
foo(1)
foo(1,2,3,4)
foo(23,34,56)

3
tests/14-repeat-sep.sh Normal file
View File

@ -0,0 +1,3 @@
# The '%' operator modifies repeating patterns, allowing you to give a separator between matches
# Example: bp -p '+"x" % ":"' will match "x", "x:x", "x:x:x", etc.
bp -p '`( +int % `, `)'

8
tests/15-repeating.in Normal file
View File

@ -0,0 +1,8 @@
(1234)
(abcd)
(abcd)
(;;;;)
(12)
(ab)
(x)
(1234567)

4
tests/15-repeating.out Normal file
View File

@ -0,0 +1,4 @@
(1234)
(abcd)
(abcd)
(;;;;)

3
tests/15-repeating.sh Normal file
View File

@ -0,0 +1,3 @@
# Numbers allow you to specify repetitions of a pattern
# Example: bp -p '3 "x"' matches "xxx"
bp -p '`( 4 . `)'

4
tests/16-lookahead.in Normal file
View File

@ -0,0 +1,4 @@
one
two
three
four

2
tests/16-lookahead.out Normal file
View File

@ -0,0 +1,2 @@
two
three

3
tests/16-lookahead.sh Normal file
View File

@ -0,0 +1,3 @@
# >pat is a lookahead
# Example: bp -p '"foo" >`(' will match "foo" only when it is followed by a parenthesis
bp -p '>`t word'

4
tests/17-lookbehind.in Normal file
View File

@ -0,0 +1,4 @@
1234
xxxx23yy
3
xxx3xx

2
tests/17-lookbehind.out Normal file
View File

@ -0,0 +1,2 @@
1234
xxxx23yy

3
tests/17-lookbehind.sh Normal file
View File

@ -0,0 +1,3 @@
# <pat is a lookbehind
# Example: bp -p '<`: word' will match words that come after a colon
bp -p '<`2 `3'

View File

@ -0,0 +1,4 @@
Uh...ok
Uhhhhh...ok
ok
xxxxokxxx

View File

@ -0,0 +1,2 @@
Uh...ok
Uhhhhh...ok

View File

@ -0,0 +1,3 @@
# Lookbehinds can have variable length.
# Example: bp -p '<(^ +`# _) "foo"' matches lines starting with "# foo", "## foo", "### foo", etc.
bp -p '<(`U +`h "...") "ok"'

4
tests/19-negation.in Normal file
View File

@ -0,0 +1,4 @@
foo
food
foobar
xxx

2
tests/19-negation.out Normal file
View File

@ -0,0 +1,2 @@
foo
food

3
tests/19-negation.sh Normal file
View File

@ -0,0 +1,3 @@
# !pat matches only if pat doesn't match
# Example: bp -p '"cat" !"aclysm"' matches the "cat" in "catatonic", but not "cataclysm"
bp -p '"foo" !"bar"'

5
tests/2-char.in Normal file
View File

@ -0,0 +1,5 @@
nope
xylophone
not this line
hexagonal
oxen

3
tests/2-char.out Normal file
View File

@ -0,0 +1,3 @@
xylophone
hexagonal
oxen

3
tests/2-char.sh Normal file
View File

@ -0,0 +1,3 @@
# Match a single character with backtick:
# Example: bp -p '`A' matches the letter "A"
bp -p '`x'

5
tests/20-submatch.in Normal file
View File

@ -0,0 +1,5 @@
one
two
three
four
five

3
tests/20-submatch.out Normal file
View File

@ -0,0 +1,3 @@
one
three
five

3
tests/20-submatch.sh Normal file
View File

@ -0,0 +1,3 @@
# pat1 ~ pat2 matches if pat2 can be found within pat1, like words containing "e"
# Example: bp -p '+`0-9 ~ `5' matches "12345" and "72581", but not "789"
bp -p 'word ~ `e'

5
tests/21-no-submatch.in Normal file
View File

@ -0,0 +1,5 @@
one
two
three
four
five

2
tests/21-no-submatch.out Normal file
View File

@ -0,0 +1,2 @@
two
four

3
tests/21-no-submatch.sh Normal file
View File

@ -0,0 +1,3 @@
# pat1 !~ pat2 matches if pat2 cannot be found within pat1, like words *not* containing "e"
# Example: bp -p '(|+`0-9|) !~ `5' matches "123" and "678", but not "456"
bp -p 'word !~ `e'

2
tests/22-replace.in Normal file
View File

@ -0,0 +1,2 @@
Microsoft
Windows

2
tests/22-replace.out Normal file
View File

@ -0,0 +1,2 @@
Micro$oft
Window$

3
tests/22-replace.sh Normal file
View File

@ -0,0 +1,3 @@
# Replacements can be done with pat => "replacement"
# Example: bp -p '"foo" => "baz"' matches "foobar" and replaces it with "bazbar"
bp -p '"s" => "$"'

View File

@ -0,0 +1,5 @@
foo(one(), two(three()));
foo();
xx()))));
xx(((();
yy)()();

View File

@ -0,0 +1,2 @@
foo(one(), two(three()));
foo();

View File

@ -0,0 +1,3 @@
# parens is a pattern matching nested parentheses
# Example: bp -p '"foo" parens' matches "foo()" or "foo(baz(), qux())", but not "foo(()"
bp -p 'id parens `;'

5
tests/24-backref.in Normal file
View File

@ -0,0 +1,5 @@
foo baz foo
xx yy xx
x x x
foo baz xx
a b c

3
tests/24-backref.out Normal file
View File

@ -0,0 +1,3 @@
foo baz foo
xx yy xx
x x x

3
tests/24-backref.sh Normal file
View File

@ -0,0 +1,3 @@
# With @-capturing, you can reference previous captures
# Example: bp -p '@first=`a-z .. first' matches "aba" and "xyzx", but not "abc"
bp -p '@first=+Abc _ +Abc _ first'

View File

@ -0,0 +1,5 @@
one
two
three
four
five

View File

@ -0,0 +1,5 @@
{o}n{e}
tw{o}
thr{e}{e}
f{o}{u}r
f{i}v{e}

View File

@ -0,0 +1,4 @@
# Captures with @ can be referenced in a replacement by @1, @2, etc.
# Example: bp -p '"=" _ @+`0-9 => "= -@1"' replaces "x = 5" with "x = -5"
# Note: @0 refers to the entire match, e.g. bp -p '"foo" => "xx@0xx"' replaces "foo" with "xxfooxx"
bp -p '@`a,e,i,o,u => "{@1}" / .'

9
tests/3-char-range.in Normal file
View File

@ -0,0 +1,9 @@
0
1
X
2
!
3
;
a
f

6
tests/3-char-range.out Normal file
View File

@ -0,0 +1,6 @@
0
1
2
3
a
f

3
tests/3-char-range.sh Normal file
View File

@ -0,0 +1,3 @@
# Character sets and ranges work with backticks
# Example: bp -p '`a-z,A-Z' matches all lowercase and uppercase letters
bp -p '`0-9,a-f'

4
tests/4-sequence.in Normal file
View File

@ -0,0 +1,4 @@
onetwo
one
two
xxxx

1
tests/4-sequence.out Normal file
View File

@ -0,0 +1 @@
onetwo

5
tests/4-sequence.sh Normal file
View File

@ -0,0 +1,5 @@
# Multiple patterns in a row represent a sequence.
# bp pattern syntax mostly doesn't care about whitespace, so you can have
# spaces between patterns if you want, but it's not required.
# Example: bp -p '"foo" `0-9' matches "foo1", "foo2", etc.
bp -p '"one" "two"'

6
tests/5-dot.in Normal file
View File

@ -0,0 +1,6 @@
aX
aY
a
Xa
y
zz

2
tests/5-dot.out Normal file
View File

@ -0,0 +1,2 @@
aX
aY

3
tests/5-dot.sh Normal file
View File

@ -0,0 +1,3 @@
# The dot matches a single character
# Example: bp -p '.'
bp -p '`a .'

5
tests/6-start-of-line.in Normal file
View File

@ -0,0 +1,5 @@
xxxxx
foo
foobar
barfoo
xxfooxx

View File

@ -0,0 +1,2 @@
foo
foobar

3
tests/6-start-of-line.sh Normal file
View File

@ -0,0 +1,3 @@
# ^ matches start of a line
# Example: bp -p '^ "x"' matches lines starting with "x"
bp -p '^ "foo"'

4
tests/7-end-of-line.in Normal file
View File

@ -0,0 +1,4 @@
xxxx
foobar
foo
barfoo

2
tests/7-end-of-line.out Normal file
View File

@ -0,0 +1,2 @@
foo
barfoo

3
tests/7-end-of-line.sh Normal file
View File

@ -0,0 +1,3 @@
# $ matches end of line
# Example: bp -p '"x" $' matches lines ending with "x"
bp -p '"foo" $'

6
tests/8-spaces.in Normal file
View File

@ -0,0 +1,6 @@
onetwo
one two
one two
one two
xxx
one;;;two

4
tests/8-spaces.out Normal file
View File

@ -0,0 +1,4 @@
onetwo
one two
one two
one two

3
tests/8-spaces.sh Normal file
View File

@ -0,0 +1,3 @@
# The _ pattern matches zero or more spaces/tabs
# Example: bp -p '`= _ "foo"' matches "=foo", "= foo", "= foo", etc.
bp -p '"one" _ "two"'

6
tests/9-ellipsis.in Normal file
View File

@ -0,0 +1,6 @@
helloworld
hello;;;world
hello1234world
goodbye
hello
helloworxx

3
tests/9-ellipsis.out Normal file
View File

@ -0,0 +1,3 @@
helloworld
hello;;;world
hello1234world

3
tests/9-ellipsis.sh Normal file
View File

@ -0,0 +1,3 @@
# The ellipsis matches text upto the following pattern, not counting newlines
# Example: bp -p '"/*" .. "*/"' matches "/* blah blah */" or "/**/"
bp -p '"hello" .. "world"'

24
tutorial.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/sh
# Run a small tutorial on basic bp functionality
tmpfile="$(mktemp /tmp/bp-tutorial.XXXXXX)"
trap 'rm "$tmpfile"' EXIT
for t in $([ $# -gt 0 ] && echo "$@" || ls -v tests/*.sh); do
echo
printf "\033[1m"
sed -n 's/^# //p' "$t"
printf "\033[0m"
printf "\033[33;1mGiven these lines: Give this output:\033[0m\n"
diff -y -W60 --color=always "${t/.sh/.in}" "${t/.sh/.out}"
while true; do
printf "\n\033[1mbp pattern: \033[0m"
read -r pat
printf "\033[0;2mRunning: \033[32m%s\033[0m\n\n" "bp -p '$pat'"
printf "\033[33;1mExpected output: Your pattern's output:\033[0m\n"
bp -p "$pat" < "${t/.sh/.in}" 2>"$tmpfile" | diff -y -W60 --color=always "${t/.sh/.out}" - && break
cat "$tmpfile"
printf "\n\033[0;1;31mSorry, try again!\033[0m\n"
done
printf "\n\033[0;1;32mCorrect!\033[0m\n"
done