Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Operator Precedence Atom Finder #16

Merged
merged 6 commits into from
Sep 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions src/atom_finder/classifier/operator-precedence.clj
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@
(order-insensitive-opt-combination (sort combination))

;;SPECIAL CASE 1: Comma operator in any combination;
(some (partial = :comma) combination)))
(some (partial = :comma) combination)
;SPECIAL CASE 2: note that the pair name is not [:bitwise_bin :bitwise-bin]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm glad you put a comment here, but what does it mean. What's the difference between bitwise_bin, bitwise-bin, and bitwise--bin?

(= [:bitwise--bin :bitwise--bin] combination)))

(defn operator-group-pair?
[node]
Expand All @@ -105,12 +107,18 @@

(defn group-pairs-in-node
"Returns all operator group pairs in a node"
[node child-groups]
(let [node-group (operator-group node)]
[node child-nodes]
(let [node-group (operator-group node) child-groups (map operator-group child-nodes)]
(cond
(instance? IASTUnaryExpression node)
[[node-group (safe-nth child-groups 0)]]

;;SPECIAL CASE 2: Two bitwise_bins that are not the same, note that the group pair name is not [:bitwise_bin and bitwise_bin]
(and (and (= :bitwise_bin node-group)
(= :bitwise_bin (safe-nth child-groups 1)))
(not (= (.getOperator node) (.getOperator (safe-nth child-nodes 1)))))
[[:bitwise--bin :bitwise--bin]]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, now I understand, but its still confusing. What about renaming these to like
[[:non-matching-bitwise :non-matching-bitwise]]
or, since it's impossible to ever have only one appear alone, maybe just
[[:non-matching-bitwise]]
or something?


(instance? IASTBinaryExpression node)
(-> node
unary-before-binary-pairs
Expand All @@ -129,16 +137,14 @@

([node collection]
(->> collection
(map operator-group)
(group-pairs-in-node node)
(remove (partial some nil?)))))

(defn operator-precedence-atom?
"Is this node an operator-precedence-atom?"
[node]
(and
(operator-group-pair? node)
(and (operator-group-pair? node)

(not (= :assign (operator-group node)))
(not (= :assign (operator-group node)))

(some confusing-operator-combination? (group-pair node))))
(some confusing-operator-combination? (group-pair node))))
112 changes: 112 additions & 0 deletions src/atom_finder/questions/redundant_parentheses.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
(ns atom-finder.questions.redundant-parentheses
(:require
[clj-jgit.internal :as giti]
[clj-jgit.porcelain :as gitp]
[clj-jgit.querying :as gitq]
[atom-finder.patch :refer :all]
[atom-finder.atom-patch :refer :all]
[atom-finder.constants :refer :all]
[atom-finder.util :refer :all]
[atom-finder.classifier :refer [operator-group confusing-operator-combination?
operator-precedence-atom?]]
[clojure.pprint :refer [pprint]]
[clojure.string :as string]
)
(:import
[org.eclipse.cdt.core.dom.ast IASTBinaryExpression]
[org.eclipse.cdt.internal.core.dom.parser.cpp CPPASTConditionalExpression]
))

(defn paren-in-children
[node]
(find-first paren-node? (children node)))

(defn redundant-paren?
[node]
(when-let* [paren-test (paren-node? node)
parent-level (precedence-level (safe-parent node))
children-level (precedence-level(first (children node)))]
(or (< children-level parent-level)
(and (= children-level parent-level)
(= node (first (children (safe-parent node))))))))

(defn atom-without-paren?
"Given a parenthesis node, would this be an operator-precedence-atom without the parentheses?"
[node]
(when-let* [parent-node (safe-parent node)
parent-group (operator-group parent-node)
child-group (operator-group (first (children node)))
opt-group-combination [parent-group child-group]]

(cond

(and (and (= :bitwise_bin parent-group)
(= parent-group child-group))
(not (= (.getOperator parent-node) (.getOperator (first (children node))))))
[:bitwise_bin :bitwise_bin]


(and (or (instance? IASTBinaryExpression parent-node)
(instance? CPPASTConditionalExpression parent-node))
(= node (first (children parent-node))))
(confusing-operator-combination? (reverse opt-group-combination))

:else(confusing-operator-combination? opt-group-combination))))

;
;========GENERAL TESTING==============
;
(->> "(fclose(f1a) | EOF) & (fclose(f1b) | EOF)" parse-expr
;print-tree
(get-in-tree [0])
;print-tree
;redundant-paren?
atom-without-paren?
)

(->> "a | b & c" parse-expr
;(get-in-tree [0])
operator-precedence-atom?
)

(def codebase_name "wcdb")

;
;=======CODEBASE DATA GATHERING==========
;
(->> (str "d:/Codebases/" codebase_name)
(pmap-dir-trees (fn [root] (filter-tree
redundant-paren?
;#(and (redundant-paren? %)(atom-without-paren? %))
;operator-precedence-atom?
root)))
flatten
(remove nil?)
;(map safe-parent)
;(map write-ast)
;(map #(spit "underclas-atom-without.txt" (str % "\r\n") :append true))
;(take 100)

;((fn [a] (prn (count a)) a))
(map atom-without-paren?)
;(map operator-precedence-atom?)
(remove (fn [input] (or (nil? input) (false? input))))
frequencies
(sort-by last)
(map #(spit (str "c:/Users/Henry/Desktop/stuff/would-be-atoms/" (str codebase_name "-rpa.txt")) (str % "\r\n") :append true))

count
prn
dorun
time-mins)

;IASTNode total: 31886519

;redundant-total: 392166

;Underclassify:
;would-be-atom: 66037

;Overclassify:
;would-be-atom: 75855

7 changes: 7 additions & 0 deletions src/atom_finder/util/10_clj_util.clj
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@
~else)
then)))

(defmacro when-let*
[bindings & then]
(if (seq bindings)
`(when-let [~(first bindings) ~(second bindings)]
(when-let* ~(drop 2 bindings) ~@then))
`(do ~@then)))

(defn bin "Convert a value to 1 or 0 based on its truthiness"
[bool] (if bool 1 0))

Expand Down
14 changes: 0 additions & 14 deletions src/atom_finder/util/cdt_util.clj
Original file line number Diff line number Diff line change
Expand Up @@ -248,20 +248,6 @@

(defn all-comments [node] (->> node root-ancestor .getComments (into [])))

(defn print-node-context
"Print the line that contains the node and the lines around it"
([node] (print-node-context 2 node))
([n-lines node]
(with-open [rdr (clojure.java.io/reader (.getContainingFilename node))]
(let [line-num (start-line node)
file-seq (line-seq rdr)
first-line (max 0 (- line-num n-lines 1))
lines-to-print (->> file-seq (drop first-line) (take (+ n-lines 1 n-lines)))]
(println "===================================================")
(doseq-indexed [line lines-to-print idx]
(println (str (+ idx first-line) (if (= (+ idx first-line 1) line-num) " >> " " ") line)))
(println "===================================================")))))

(defn count-nodes
"Count the size of the ast"
[node]
Expand Down
12 changes: 8 additions & 4 deletions src/atom_finder/util/classifier_util.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
IASTBinaryExpression IASTLiteralExpression IASTForStatement
IASTFunctionDefinition IASTArraySubscriptExpression IASTCastExpression
IASTFunctionCallExpression IASTFieldReference IASTFunctionDefinition)
'(org.eclipse.cdt.internal.core.dom.parser.cpp CPPASTExpressionList CPPASTConditionalExpression))
'(org.eclipse.cdt.internal.core.dom.parser.cpp CPPASTQualifiedName CPPASTExpressionList CPPASTConditionalExpression CPPASTNewExpression CPPASTDeleteExpression))

(defn function-node? [node] (instance? IASTFunctionDefinition node))

Expand Down Expand Up @@ -214,14 +214,16 @@

(defn in-function? [node] (ancestral-instance? IASTFunctionDefinition node))

;;Note: Operators missing from the list: (scope/ resolution ::) (memory allocation/ new new[] delete delete[]) (pointer-to-member/ ->* .*)
(defmulti precedence-level "returns the precedence level of the node" class)
(defmethod precedence-level :default [node]
(let [precedence-list
{IASTArraySubscriptExpression 2
{CPPASTQualifiedName 1
IASTArraySubscriptExpression 2
IASTFieldReference 2
IASTCastExpression 2
IASTFunctionCallExpression 2
CPPASTNewExpression 3
CPPASTDeleteExpression 3
CPPASTConditionalExpression 15
CPPASTExpressionList 16}]
(precedence-list (type node))))
Expand All @@ -242,7 +244,9 @@
(precedence-list (.getOperator node))))
(defmethod precedence-level IASTBinaryExpression [node]
(let [precedence-list
{IASTBinaryExpression/op_modulo 5
{IASTBinaryExpression/op_pmdot 4
IASTBinaryExpression/op_pmarrow 4
IASTBinaryExpression/op_modulo 5
IASTBinaryExpression/op_multiply 5
IASTBinaryExpression/op_divide 5
IASTBinaryExpression/op_plus 6
Expand Down
15 changes: 15 additions & 0 deletions src/atom_finder/util/writer-util.clj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,21 @@
node 1 []))


(defn print-node-context
"Print the line that contains the node and the lines around it"
([node] (print-node-context 2 node))
([n-lines node]
(with-open [rdr (clojure.java.io/reader (.getContainingFilename node))]
(let [line-num (start-line node)
file-seq (line-seq rdr)
first-line (max 0 (- line-num n-lines 1))
lines-to-print (->> file-seq (drop first-line) (take (+ n-lines 1 n-lines)))]
(println "===================================================")
(doseq-indexed [line lines-to-print idx]
(println (str (+ idx first-line) (if (= (+ idx first-line 1) line-num) " >> " " ") line)))
(println "===================================================")))))


(def ast-writer (ASTWriter.))
(defn write-ast [node] (.write ast-writer node))

Expand Down
6 changes: 3 additions & 3 deletions src/conf/henry.edn
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
:gcc-path "~/opt/src/gcc",
:ag-path "~/opt/src/the_silver_searcher",
:github-top-c "~/opt/src/github-top-c"
:gcc-path "d:/Codebases/gcc/opt/src/gcc",
:ag-path "d:/Codebases/gcc/opt/src/the_silver_searcher",
:github-top-c "d:/Codebases/gcc/opt/src/github-top-c"
}
3 changes: 3 additions & 0 deletions src/test/resources/operator-precedence.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,7 @@ int main(){

~str++;//<true>
--~str;

a = a << 1 << 2; //<false>, underclassify
a = a | 2 & 3; //<true>
}