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

infix-operator-precedence atom #10

Merged
merged 23 commits into from
Jul 11, 2017
Merged
Show file tree
Hide file tree
Changes from 4 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
319 changes: 319 additions & 0 deletions hs_err_pid10868.log

Large diffs are not rendered by default.

327 changes: 327 additions & 0 deletions hs_err_pid7776.log

Large diffs are not rendered by default.

2,383 changes: 2,383 additions & 0 deletions replay_pid10868.log

Large diffs are not rendered by default.

3,125 changes: 3,125 additions & 0 deletions replay_pid7776.log

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/atom_finder/classifier.clj
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
(ValidatedAtom :omitted-curly-braces omitted-curly-braces-atom? (default-finder omitted-curly-braces-atom?))
(ValidatedAtom :assignment-as-value assignment-as-value-atom? (default-finder assignment-as-value-atom?))
(ValidatedAtom :macro-operator-precedence macro-def-precedence-atom? macro-operator-precedence-atoms)
]
(ValidatedAtom :operator-precedence operator-precedence-atom? (default-finder operator-precedence-atom?))]
)

(def atom-lookup (into {} (map #(vector (:name %1) %1) atoms)))
139 changes: 0 additions & 139 deletions src/atom_finder/classifier/infix-operator-precedence.clj

This file was deleted.

80 changes: 0 additions & 80 deletions src/atom_finder/classifier/infix-operator-precedence.supposed-clj

This file was deleted.

131 changes: 131 additions & 0 deletions src/atom_finder/classifier/operator-precedence.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
(in-ns 'atom-finder.classifier)
(import '(org.eclipse.cdt.core.dom.ast IASTBinaryExpression IASTConditionalExpression IASTUnaryExpression)
'(org.eclipse.cdt.internal.core.dom.parser.cpp CPPASTConditionalExpression CPPASTExpressionList CPPASTFieldReference))

(defmulti operator-group"Returns the name of the operator group that the node belongs to, nil not defined in this operator-group" class)
(defmethod operator-group :default [node]
(let [operator-group-table
{CPPASTConditionalExpression :cond
CPPASTExpressionList :comma
CPPASTFieldReference :field_ref}]
(->> node type operator-group-table)))
(defmethod operator-group IASTUnaryExpression [node]
(let [operator-group-table
{IASTUnaryExpression/op_postFixDecr :de_incr
IASTUnaryExpression/op_postFixIncr :de_incr
IASTUnaryExpression/op_minus :arith_unary
IASTUnaryExpression/op_plus :arith_unary
IASTUnaryExpression/op_prefixDecr :de_incr
IASTUnaryExpression/op_prefixIncr :de_incr
IASTUnaryExpression/op_amper :pointer
IASTUnaryExpression/op_star :pointer
IASTUnaryExpression/op_not :not
IASTUnaryExpression/op_tilde :bitwise}]
(->> node .getOperator operator-group-table)))
(defmethod operator-group IASTBinaryExpression [node]
(if (assignment? node)
:assign

(let [operator-group-table
{IASTBinaryExpression/op_modulo :non-asso
IASTBinaryExpression/op_multiply :multiply
IASTBinaryExpression/op_divide :non-asso
IASTBinaryExpression/op_plus :add
IASTBinaryExpression/op_minus :non-asso
IASTBinaryExpression/op_shiftLeft :bitwise
IASTBinaryExpression/op_shiftRight :bitwise
IASTBinaryExpression/op_greaterThan :compare
IASTBinaryExpression/op_greaterEqual :compare
IASTBinaryExpression/op_lessThan :compare
IASTBinaryExpression/op_lessEqual :compare
IASTBinaryExpression/op_equals :compare
IASTBinaryExpression/op_notequals :compare
IASTBinaryExpression/op_binaryAnd :bitwise
IASTBinaryExpression/op_binaryXor :bitwise
IASTBinaryExpression/op_binaryOr :bitwise
IASTBinaryExpression/op_logicalAnd :and
IASTBinaryExpression/op_logicalOr :or}]
(->> node .getOperator operator-group-table))))


(defn specific-confusing-operator-combination?
"if the combination of groups of operators exists in this set, then the combination is confusing"
[combination]
(some #(= % combination) (map sort #{[:de_incr :pointer] [:multiply :add] [:arith_unary :add] [:arith_unary :multiply] [:and :add] [:and :multiply] [:and :arith_unary] [:or :add] [:or :multiply] [:or :arith_unary] [:or :and] [:not :add] [:not :multiply] [:not :arith_unary] [:not :and] [:not :or]
Copy link
Owner

@dgopstein dgopstein Jul 11, 2017

Choose a reason for hiding this comment

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

  1. please use shorter lines, this is hard to read
  2. when you map over a set #{}, you get back a seq '(), so I wouldn't even bother using set notation to begin with, because its misleading.
  3. you don't sort the combination, which means that if you pass in [:pointer :de_incr] it won't match even when it should

In total I'd probably do something like:

(def confusing-op-combinations (->> [[:de_incr :pointer] [:multiply :add] ...] (map sort) (into #{})))
(defn specific-confusing-operator-combination? [combination] (confusing-op-combinations (sort combination)))

;;[:compare :and] [:compare :or] // Underclassify
[:compare :not] [:compare :compare] [:pointer :add] [:cond :arith_unary] [:cond :and] [:cond :or] [:cond :not] [:cond :compare] [:cond :cond] [:non-asso :add] [:non-asso :multiply] [:non-asso :arith_unary] [:non-asso :and] [:non-asso :or] [:non-asso :not] [:non-asso :non-asso] [:field_ref :pointer]})))

(def always-confusing-operator-groups
"If any of these operator groups is used along with another operator, then it is confusing"
#{:bitwise :comma})

(defn confusing-operator-combination?
"Is this combination of the operator groups confusing?"
[combination]
(or (specific-confusing-operator-combination? combination)
(some (partial contains? always-confusing-operator-groups) combination)))

(defn operator-group-pair?
[node]
(and (operator-group node)
(some operator-group (children node))))

(defn group-pair
"returns a collection of operator group pairs between the node and its children
, if a second parameter is passed, use that as the collection instead of the children"
([node]
(->> node
children
(map operator-group)
(remove nil?)
(map (fn [child-group] (sort [(operator-group node) child-group])))))
Copy link
Owner

Choose a reason for hiding this comment

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

This is a very common pattern of have 2 function arities, both of which do the same thing, one using a predefined value. I usually define the unary version in terms of the binary:

([node] (group-pair node (children node)))


([node collection]
(->> collection
(map operator-group)
(remove nil?)
(map (fn [child-group] (sort [(operator-group node) child-group]))))))


;;
;;The following 3 functions are for the binary operator special case
Copy link
Owner

Choose a reason for hiding this comment

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

s/binary/unary/

;;
(defn rvalue-unary-operator?
"Is this a unary operator that can operate on an rvalue? (! - + *)"
[node]
(let [node-group (operator-group node)]
(or (= :arith_unary node-group)
(= :not node-group)
(= :pointer node-group))))
Copy link
Owner

Choose a reason for hiding this comment

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

If you wanted, this function could be a single line

(def rvalue-unary-operator? (comp #{:arith_unary :not :pointer} operator-group))

But in general, I'm more a fan of naming your data than naming your behaviors, so might go:

(def rvalue-unary-ops #{:arith_unary :not :pointer})


(defn unbracktted-unary-in-children
Copy link
Owner

Choose a reason for hiding this comment

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

What is unbracktted?

"Is this node not a bracket and constains unary operator in its children?"
[node]
(if (not= "()" (write-node node))
Copy link
Owner

Choose a reason for hiding this comment

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

I'd love to see a predicate parens?, but I'd probably implement it (instance? IASTParenthesisExpression) or whatever.

(filter-tree #(rvalue-unary-operator? %) node)))

(defn group-pairs-in-binary-operator
"Special function for returning a collection of operator group in binary operator's children, binary operator should ignore some groups of operators in its second operand"
[node]
(->> (concat [(get-in-tree [0] node)
(if (not (rvalue-unary-operator? (get-in-tree [1] node)))
(get-in-tree [1] node) nil)]

(unbracktted-unary-in-children (get-in-tree [0] node)))
(map operator-group)
(remove nil?)
(map (fn [child-group] (sort [(operator-group node) child-group])))))



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

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

(if (instance? IASTBinaryExpression node)
(some confusing-operator-combination? (group-pairs-in-binary-operator node))
(some confusing-operator-combination? (group-pair node)))))
Binary file removed src/conf/conf.end.lnk
Binary file not shown.
Loading