The construction of a mapping rules dictionary is a crucial step in achieving syntax transformation. This process primarily involves two steps:
3.1.1. Construction of Context-Aware Technology
Nodes in the syntax tree, such as variable declarations, operators, and punctuation, have clear semantics and don’t require extra contextual information for feature mapping. They can be mapped using preconstructed mapping dictionaries. However, for context-sensitive structure type nodes, such as those representing control flow structures (e.g., if statements, for loops, while loops), considering the surrounding context is essential for accurate mapping.Context-aware syntax mapping using the described technique involves determining the context window size and constructing mappings based on contextual rules. This technique is applied to nodes that abstract code control flow structures, functions, and classes, which constitute the fundamental structure and semantic representation of the code
As illustrated in
Figure 2, for nodes requiring context-aware mapping, a relevant code snippet is extracted from the source code as context information, based on the context window size. Following the mapping rules, this extracted context information is then mapped to the corresponding Java nodes. With the help of mapping rules, the specific node information is matched with the corresponding Java syntax tree node based on its semantic and structural attributes. This process achieves mapping for context-sensitive structural nodes. For example, for an If condition statement node in the syntax tree, the context window size is used to determine the number of code lines in the conditional expression and the code lines within the branches (if and else branches). The conditional expression and branch code lines are extracted to form the context information. After completing the structural mapping of the syntax tree, internal node information is subject to single-node mapping. This entails replacing the node names in the feature sequence according to the node replacement rules in the mapping dictionary. The obtained context information is merged with the feature information of the current node, resulting in the final feature representation.
As shown in
Table 1, context-aware mapping is applied to seven types of syntax tree nodes based on their structural context. These types include if statement nodes, while loop nodes, for loop nodes, switch statement nodes, function nodes, class nodes, and try statement nodes. For these seven syntax types, a custom function is employed to identify and determine code blocks, followed by extending the context window based on the respective code block. Once the context window is established, the specific information of each node requiring context-aware mapping is merged with the extracted context information to create a comprehensive feature representation that combines both code structure and semantics. Since different programming languages share similar representations for these structures, the formulation of these rules is language-agnostic. The dynamic generation of context windows, on the other hand, retains language-specific characteristics, enabling effective noise reduction in the code.
3.1.2. Construction of Point-to-Point Mapping Method
The construction of the point-to-point mapping method involves an algorithm based on semantic similarity for node mapping. This algorithm efficiently, accurately, and with strong scalability clusters syntax tree node information using token semantic similarity for node mapping. The process is depicted in
Figure 3. Initially, the syntax trees of collected target and source files are serialized to form sequences of tokens from different languages. These tokens are then subjected to Word2Vec vectorization, followed by measuring token similarity using cosine similarity. Subsequently, the k-means algorithm is applied to cluster tokens based on their similarity, grouping similar nodes into the same cluster. This process establishes relationships of semantic similarity among nodes.
To establish semantic-based mapping relationships between nodes from different programming languages, the initial step involves collecting token information from diverse programming languages. The similarity between tokens corresponds to the naming of syntax tree nodes, ultimately constructing mapping rules within the mapping dictionary. Tokens represent the fundamental constituents of code, as compilers break down code into individual tokens during lexical analysis, followed by subsequent syntax analysis and execution. Tokens are categorized into ten classes based on their lexical attributes.
As depicted in
Table 2, identifiers are language-specific and are not suitable for using a general mapping approach. Special characters (such as colons, commas, periods, etc.), numbers, boolean constants, and strings typically represent symbols with fixed meanings that do not involve specific code structures or semantic conversions, and they do not exhibit language variations. Additionally, syntax trees do not include comment information or code formatting details. Therefore, these types of token information retain the characteristics of the original language during the syntax tree mapping process and are not subjected to mapping treatment.
Furthermore, some common operators, such as addition (+) and comparison operators (e.g., ==, <, >, etc.), are similar across most programming languages. However, for operators that have different representations or functionalities in various programming languages, simple rule additions can be made in the pre-constructed dictionary. For example, the logical AND operator is represented as "&&" in the C language and "and" in Python. This requires adding rules to the dictionary accordingly. In summary, the token types that require discovering mapping rules through semantic similarity are literal types (such as int, bool, String, etc.) and keywords (such as if, else, for, etc.).
As illustrated in
Figure 4, AST-FMVD employs the k-means similarity algorithm to cluster tokens based on their similarity scores. Tokens with higher semantic similarity are grouped together within the same cluster, thus establishing relationships of semantic similarity among nodes.Let
denote the set of all tokens, and
represent the cosine similarity between tokens
and
. The specific steps are outlined as follows:
1. Calculate similarity matrix: For all tokensand, compute the cosine similarity between them. This can be accomplished using Word2Vec vectorized representations and the cosine similarity formula.
2. Initialize cluster assignments: Initialize a cluster assignmenfor each token initially assigning each token to its own cluster.
3. Iterate to update cluster assignments: Iteratively update cluster assignments until convergence. For each token,perform the following operations based on specific conditions:
Ifis an outlier, assign it to the cluster of the other token that has the minimum similarity with,i.e.,;
If the cluster containingalready includes more than two tokens from different languages, assignto the cluster of the other token that has the minimum similarity with,i.e.,;
If the cluster containingincludes two tokens from different languages andis not an outlier, assignto the cluster of the other token that has the maximum similarity with, i.e., ;
4. Check for convergence: After each iteration, check if the cluster assignments have changed. If the assignments remain unchanged, the algorithm converges.
By performing similarity-based clustering analysis on the syntax tree nodes of the two categories of tokens from different languages, direct mapping relationships among most nodes can be obtained. However, within the clustering structure, there might be outliers and clusters of nodes from the same language. For these types of nodes, we can extract and analyze them separately, and construct mapping rules tailored to their characteristics. The additional node mapping rules are presented in
Table 3.