Вдохновившись темой https://xss.pro/threads/106900/#post-748687 выложу код для реализации парса С/C++
Нам понадобится всего лишь Rust
Cargo.toml
main.rs (основной код программы который переписывает AST)
Вкратце код меняет trash code hera на /* Random int = ...*/
То есть после запуска получим
Вообщем полезная утилита для морфа кода. Такой метод конти юзали ( в локере можете увидеть) )
Нам понадобится всего лишь Rust
Cargo.toml
Код:
[dependencies]
tree-sitter = "0.20.10"
tree-sitter-cpp = "0.20.3"
rand = "0.8.5"
main.rs (основной код программы который переписывает AST)
Код:
extern crate tree_sitter;
extern crate tree_sitter_cpp;
extern crate rand;
use tree_sitter::{Parser, Node};
use rand::Rng;
fn main() {
let code = r#"
#include <iostream>
#include <vector>
class Solution {
public:
double findMedianSortedArrays(std::vector<int>& nums1, std::vector<int>& nums2) {
int m = nums1.size(), n = nums2.size();
if(m > n) return findMedianSortedArrays(nums2, nums1);
int lo = 0, hi = m, mid = (m + n + 1)/2;
while(lo <= hi){
int i = (lo + hi)/2;
int j = mid - i;
if(i < m && nums2[j - 1] > nums1[i])
lo = i + 1;
else if(i > 0 && nums1[i - 1] > nums2[j])
hi = i - 1;
else{
int maxLeft = (i == 0) ? nums2[j - 1] : (j == 0) ? nums1[i - 1] : std::max(nums1[i - 1], nums2[j - 1]);
int minRight = (i == m) ? nums2[j] : (j == n) ? nums1[i] : std::min(nums1[i], nums2[j]);
return (m + n) % 2 ? maxLeft : (maxLeft + minRight) / 2.0;
}
}
}
};
int main() {
/* trash code here */
std::vector<int> nums1 = {1, 3};
std::vector<int> nums2 = {2};
Solution solution;
/* trash code here */
double median = solution.findMedianSortedArrays(nums1, nums2);
std::cout << "Median: " << median << std::endl;
/* trash code here */
return 0;
}
"#;
let mut parser = Parser::new();
parser.set_language(tree_sitter_cpp::language()).expect("Error loading CPP grammar");
let parsed = parser.parse(code, None).expect("Parsing error");
let root_node = parsed.root_node();
let mut code_string = String::from(code);
let mut replacements = Vec::new();
traverse_node(root_node, &code_string, 0, &mut replacements);
for (start_byte, end_byte) in replacements.iter().rev() {
let mut rng = rand::thread_rng(); // Initialize the random number generator
let random_integer: i32 = rng.gen_range(1..=1000000);
let formatted_string = format!("/* Random int = {} */", random_integer);
code_string.replace_range(*start_byte..*end_byte, &formatted_string);
}
println!("Modified code:\n{}", code_string);
}
fn traverse_node(node: Node, code: &str, level: usize, replacements: &mut Vec<(usize, usize)>) {
if node.kind() == "comment" {
let comment_text = node.utf8_text(code.as_bytes()).unwrap();
if comment_text.contains("trash code here") {
let start_byte = node.start_byte();
let end_byte = node.end_byte();
replacements.push((start_byte, end_byte));
}
}
let mut cursor = node.walk();
for child in node.named_children(&mut cursor) {
traverse_node(child, code, level + 1, replacements);
}
}
Вкратце код меняет trash code hera на /* Random int = ...*/
То есть после запуска получим
C++:
Modified code:
#include <iostream>
#include <vector>
class Solution {
public:
double findMedianSortedArrays(std::vector<int>& nums1, std::vector<int>& nums2) {
int m = nums1.size(), n = nums2.size();
if(m > n) return findMedianSortedArrays(nums2, nums1);
int lo = 0, hi = m, mid = (m + n + 1)/2;
while(lo <= hi){
int i = (lo + hi)/2;
int j = mid - i;
if(i < m && nums2[j - 1] > nums1[i])
lo = i + 1;
else if(i > 0 && nums1[i - 1] > nums2[j])
hi = i - 1;
else{
int maxLeft = (i == 0) ? nums2[j - 1] : (j == 0) ? nums1[i - 1] : std::max(nums1[i - 1], nums2[j - 1]);
int minRight = (i == m) ? nums2[j] : (j == n) ? nums1[i] : std::min(nums1[i], nums2[j]);
return (m + n) % 2 ? maxLeft : (maxLeft + minRight) / 2.0;
}
}
}
};
int main() {
/* Random int = 446381 */
std::vector<int> nums1 = {1, 3};
std::vector<int> nums2 = {2};
Solution solution;
/* Random int = 259191 */
double median = solution.findMedianSortedArrays(nums1, nums2);
std::cout << "Median: " << median << std::endl;
/* Random int = 629982 */
return 0;
}
Вообщем полезная утилита для морфа кода. Такой метод конти юзали ( в локере можете увидеть) )