-
Notifications
You must be signed in to change notification settings - Fork 1
/
delete-useless-parentheses.sh
132 lines (117 loc) · 3.64 KB
/
delete-useless-parentheses.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#
test=0
while getopts 'htx' opt; do
case "$opt" in
t)
test=1
;;
x)
set -x
;;
?|h)
cat - <<EOF
NAME
$(basename $0) - delete useless parentheses in an Antlr4 grammar
SYNOPSIS
$(basename $0) ([-x | -h])* [grammar-files]
DESCRIPTION
Delete useless parentheses in an Antlr4 grammar.
This script must be run under Linux Bash or Windows MSYS2 Bash or Windows WSL Linux.
OPTIONS
-h
Output this help message.
-t
Test first and display using trcaret.
-x
Execute "set -x" to debug script.
EXAMPLE USAGE
git clone https://github.com/antlr/grammars-v4.git
cd grammars-v4/abb
$(basename $0) *.g4
cd ../java/java20
dotnet trparse -- *.g4 | $(basename $0)
EOF
exit 0
;;
esac
done
shift $((OPTIND - 1))
files=("$@")
temp=`mktemp`
temp2=`mktemp`
if [ ${#files[@]} -gt 0 ]
then
if [ $test -eq 1 ]
then
dotnet trparse -- -l -t ANTLRv4 ${files[@]} > $temp
else
dotnet trparse -- -t ANTLRv4 ${files[@]} > $temp
fi
else
cat - > $temp
fi
if [ $test -eq 0 ]
then
command="dotnet trquery -- delete "
else
command="dotnet trxgrep -- "
fi
cat $temp | $command '
(: Find all blocks... :)
//(block[
(: except not one of these ... :)
(: do not flag "a ( b | c )* d" or with other operator :)
not(./parent::ebnf/blockSuffix and ./altList/OR)
(: do not flag "(a ( b | c )* )?" because it is not the same as the '*?'-operator. :)
and not(./parent::ebnf/blockSuffix/ebnfSuffix/QUESTION and ./altList[count(./*) = 1]/alternative[count(./*) = 1]/element[count(./*) = 1]/ebnf[./block and ./blockSuffix/ebnfSuffix/*])
(: do not flag blocks that contain a lot of elements like "(a b c)*" :)
and not(./parent::ebnf/blockSuffix and count(./altList/alternative/element) > 1)
(: do not flag if there are alts *and* it is preceed or followed by an element,
e.g., "a (b | c d)" or "(a | b) c". :)
and not(./altList/OR and ../../following-sibling::element)
and not(./altList/OR and ../../preceding-sibling::element)
(: do not flag "a ( v += b )* c" or with other operator :)
and not(
(
(count(./altList/alternative/element/labeledElement/ASSIGN) > 0)
or
(count(./altList/alternative/element/labeledElement/PLUS_ASSIGN) > 0)
)
and (count(./parent::ebnf/blockSuffix) > 0)
)
and not(
(
(count(./parent::labeledElement/ASSIGN) > 0)
or
(count(./parent::labeledElement/PLUS_ASSIGN) > 0)
)
)
]
|
lexerBlock[
(: except not one of these ... :)
not(./parent::lexerElement/ebnfSuffix and ./lexerAltList/OR) and
not(./parent::lexerElement/ebnfSuffix and count(./lexerAltList/lexerAlt/lexerElements/lexerElement) > 1) and
not(./lexerAltList/OR and ../following-sibling::lexerElement) and
not(./lexerAltList/OR and ../preceding-sibling::lexerElement) and
(: not(./parent::lexerElement/ebnfSuffix and ./lexerAltList/lexerAlt/lexerElements/lexerElement/lexerAtom/characterRange) and :)
not(count(./lexerAltList/lexerAlt) > 1 and ../../../lexerCommands) and
not(./parent::labeledLexerElement/(ASSIGN or PLUS_ASSIGN))
]
|
blockSet[
(: except not one of these ... :)
not(./OR)
])/(LPAREN | RPAREN)' > $temp2
if [ $test -eq 0 ]
then
if [ ${#files[@]} -gt 0 ]
then
cat $temp2 | trsponge -c
else
cat $temp2 | trtext
fi
else
cat $temp2 | trcaret
fi
rm -f $temp $temp2