Archive for 算法-编程

开始想用python做一个键盘记录的工具,搜索linux keyboard hook,发现找不到东西。后来发现原来linux直接读设备文件就行了,才恍然大悟。 /dev/input/下有十多个event。要找到键盘对应的event,查看grep keyboard /proc/bus/input/devices -A 12。 然后找到一点资料,自己写了一段程序:

# coding: utf-8
import os
import struct

fmt = "llHHI"
size = struct.calcsize(fmt)
filename = "/dev/input/event3"

fd = os.open(filename, os.O_RDWR)
while 1:
    op = os.read(fd, size)
    timeval, suseconds, typ, code, value = struct.unpack(fmt, op)
    print typ, code, value
最后又找到两个库,用来读或模拟键盘按键的(或别的设备)。python-evdev和python-uinput。

Continue

啃了python源代码,从python.c开始慢慢看到token获取,学到很多东西,但是我看到python源代码也有很多可以优化的地方。很多参数、变量可以不要的,同样的判断在不同地方使用的不同方法,我靠看的我晕头转向。一到晕头转向的时候,我就重新从有疑问的地方再走一遍,认真看关键代码,然后才能看懂这一部分的功能。 语言的基本语法想个差不多了,天马行空了一下,与开始想的差距太大。

Continue

n久前就有这样的冲动,这次读了淫神的代码后,决定还是动一下手。 语言语法主要类似python的,靠缩进来定义代码块,动态语言/静态语言还没想好0 0(应该会静态类型)。 以前想做的时候看过,flex,yacc/bison什么的,看了淫神的代码突然想自己实现一下,问题是难免的,出现问题解决问题。不下手不会知道问题会出在哪,这也是成长过程。看了淫神的代码开始想使用python写,后来觉得有必要复习一下c了,c语言用的太少了,是时候提高一下水平了。 再一个临时的决定是使用llvm,虽然现在还不是很懂其中的奥秘,看看文档慢慢来吧。这也是发现现在好多语言都在用来提示速度,dropbox也在搞py的实现,期待能达到更快的速度。 感觉如果用flex,bison ,llvm 写一个语言应该超简单。。。当然是写一个玩的而不是用的。 我看了淫神的代码 ,然后去翻python的源代码parse部分,无从下手,打眼也抽不出来各部分功能,然后就放弃了,自己慢慢搞。汗 更新 周末,屋里又看了一下python parser部分的源代码,找到了基本流程,开始基本就在Parser/pgenmain.c和Python/pythonrun.c这两个文件,流程我也过了一遍,函数里边具体的分析没仔细看。突然感觉流程都差不多,我可以借鉴一下python的c代码,质量不用说肯定是不错的,偶卡卡。

Continue

1 安装 下载的最新的3.4, http://llvm.org/releases/download.html#3.4 Clang source code (.sig) LLVM source code (.sig) Compiler RT source code (.sig) 官方安装文档:http://llvm.org/docs/GettingStarted.html#getting-started-quickly-a-summary 下载的源码主要解压到正确目录就行了. mkdir build cd build ../configure make make install 编译的二进制文件在llvm-3.4/build/Release+Asserts/bin 搞定了 clang --version clang version 3.4 (tags/RELEASE_34/final) Target: x86_64-unknown-linux-gnu Thread model: posix 源里边最新的是3.3的 2 写一个c的hello world

#include 

int main() {
  printf("hello world\n");
  return 0;
}
听说clang比gcc速度快。 clang hello.c -o hello 这里和gcc生成一样的系统执行文件 生成llvm的字节码文件 clang -O3 -emit-llvm hello.c -c -o hello.bc 两种形式运行 ./hello lli hello.bc

Continue

好吧,我先把yin语言的java代码看了个差不多才想编译一下,主要原因还是想打印点测试的东西,并不是想写点什么。 总的来说像淫神说的,写得代码却是容易阅读。我java只是上学的时候开过课,再没用过,看的过程中只查了两三个的函数就看完了。看完了发现写个括号语言不算太难0 0,我的意思仅仅是学习知识不是编写一个可以用的语言。编译原理的课也开了,都是理论,传说中的龙书又是啥书的,我几分钟看来一遍,感觉和课本没什么区别。看一个编写初期的代码更容易理解一些东西。以前也想自己实现过,想想解析代码的复杂程度就怕了。 环境需求,参照github的wiki上。 java jdk 1.7,ubuntu12.04自带好像是openjdk 我以前搞安卓游戏的时候换过了。 maven 3.2 我直接从官网下载的二进制版本,http://maven.apache.org/download.cgi。解压到/opt/maven-3.2.1,vim /home/a0x55aa/.bashrc,添加export PATH=/opt/maven-3.2.1/apache-maven-3.2.1/bin:$PATH。source一下。mvn -version看一下。应该没问题了 然后mvn compile,自动下了一堆的东西0 0。pom.xml配置文件也看不懂。 mvn exec:java -Dexec.mainClass="org.yinwang.yin.Interpreter" -Dexec.args="tests/assign1.yin" 又下载了一堆东西。。。java果然不是一般人能搞的。我草。太恶心了,都不知道什么用。

Continue

函数

fn line(a: int, b: int, x: int) -> int {
    return a * x + b;
}
使用fn定义个函数,参数是在括号里边的name:type对,->后面跟返回值类型。 最后一行没有分号,可以省略return,将最为整个代码段的值返回。返回空或者(),可以不写返回类型。函数参数支持模式匹配。
fn first((value, _): (int, f64)) -> int { value }
析构函数 析构函数用来定义处理文件,socket,对内存的释放。当不再访问之后,对象的析构函数将被调用,防止访问释放的资源可能会产生的动态错误。当一个任务失败,在任务中的所有对象析构函数将被调用。 定义一个链表
enum List {
    Cons(...),
    Nil
}
enum List {
    Cons(u32, ~List),
    Nil
}
哈哈 像极了clisp里边的列表, Cons应该是一个元组,元组第一个元素u32,第一个元素指向list的下一个元素。 上边的定义类似递归的思想,list有两种情况,nil是list,Cons(u32, ~List)也是list。第二种情况里边又包含一个list,这个list也应该是前边两种类型。哈哈 Cons这个名字可以随便起的,不过最好还是不改的。官方文档没有说明,多少有点疑惑(读英文文档也没自信,不知道对不对) 波浪号是必须的,表示一个指向list类型值的指针。
let list = Cons(1, ~Cons(2, ~Cons(3, ~Nil)));

Continue

结构体

struct Point {
    x: f64,
    y: f64
}
let mut mypoint = Point { x: 1.0, y: 1.0 };
let origin = Point { x: 0.0, y: 0.0 };

mypoint.y += 1.0; // `mypoint` is mutable, and its fields as well
origin.y += 1.0; // ERROR: assigning to immutable field
match mypoint {
    Point { x: 0.0, y: yy } => println!("{}", yy),
    Point { x: xx,  y: yy } => println!("{} {}", xx, yy)
}

match mypoint {
    Point { x, .. } => println!("{}", x)
}
如果结构体变量是可变的,那么结构体里边的变量也是可变的。,..表示你忽略别的所有其他struct成员变量。 枚举
enum Direction {
    North,
    East,
    South,
    West
}
enum Color {
  Red = 0xff0000,
  Green = 0x00ff00,
  Blue = 0x0000ff
}
enum Shape {
    Circle(Point, f64),
    Rectangle(Point, Point)
}
use std::f64;
fn area(sh: Shape) -> f64 {
    match sh {
        Circle(_, size) => f64::consts::PI * size * size,
        Rectangle(Point { x, y }, Point { x: x2, y: y2 }) => (x2 - x) * (y2 - y)
    }
}
第一个元素没有定义值,默认为0,依次加1。当为整数型,可用ad操作符转换成整数。进行匹配的时候,下划线代表忽略一个,”..“表示忽略所有。 元组
let mytup: (int, int, f64) = (10, 20, 30.0);
match mytup {
  (a, b, c) => println!("{}", a + b + (c as int))
}
元组结构体
struct MyTup(int, int, f64);
let mytup: MyTup = MyTup(10, 20, 30.0);
match mytup {
  MyTup(a, b, c) => println!("{}", a + b + (c as int))
}
相比元组,元组结构体有名字,所以Foo(1,2)和Bar(1,2)是不同的类型值。 只有一个元素的结构体元组是”newtype“,新名字是一个新类型,而不是一个已存在类型的别名。 碉堡的用法:
let length_with_unit = Inches(10);
let Inches(integer_length) = length_with_unit;
println!("length is {} inches", integer_length);
看完第五节,我已经想大体看完写点程序了。前边大部分也能看看程序就大体知道啥意思,不过还是把英文说的小细节看了一下。看到这里我觉得rust比golang更好,说不上来是不是细节的用法,他们有很多相似,但是感觉rust更顺眼一些。看的过程中我都怀疑是不是一帮人搞的两个差不多的东西。。

Continue

if语句的判断式必须是bool类型的,不能有隐式的转换。如果if分支里边最后是一个值,那么每一个分支都必须是一个值。 match语句类似c的switch。当找到一个匹配项,只执行改分支,不需要加一个break。一个分支匹配多个不同的值用“|”分隔。可以用“M..N”表示两个数字值范围。下划线匹配任何单个值。 每一个分支之间用逗号分隔,如果用大括号包含就可以省略逗号。

match my_number {
  0     => println!("zero"),
  1 | 2 => println!("one or two"),
  3..10 => println!("three to ten"),
  _     => println!("something else")
}
use std::f64;
use std::num::atan;
fn angle(vector: (f64, f64)) -> f64 {
    let pi = f64::consts::PI;
    match vector {
      (0.0, y) if y < 0.0 => 1.5 * pi,
      (0.0, _) => 0.5 * pi,
      (x, y) => atan(y / x)
    }
}
变量名可以匹配任意值,并且这个变量名绑定匹配到的值,可在分支里进行操作。“variable @ pattern”后边是匹配规则,前边是绑定的变量名。任何一个match分支可以有一个if语句,在匹配成功后进行判断。 循环。while的条件也必须是bool类型,break停止循环,continue进行下次循环。loop相当于while ture。for的两个例子:
for n in range(0, 5) {
    println!("{}", n);
}
let s = "Hello";
for c in s.chars() {
    println!("{}", c);
}
for可用于任何迭代器。  

Continue

好久没写博客了,越来越懒。碰到问题,文档上有的,或者可以搜索到的就懒得总结了,也经常要找多次。准备经常更新。 rust很早之前看过,那时候感觉标准库太少了,特别网络相关的根本找不到。0.9的时候我看好像有了,现在0.1了网络相关的已经有了,准备学习一下rust语言。 hello.rs  

fn main() {
    println!("hello?你好");
}
custc hello.rs ./hello rust所有的声明必须在函数里边,rust可以编译成库文件被别的程序包含,甚至是非rust程序。 println!这种标示符后面跟一个叹号的是宏调用。宏调用感觉好强大,还没仔细看。先记几个连接 http://static.rust-lang.org/doc/0.10/guide-macros.html http://static.rust-lang.org/doc/master/std/fmt/index.html#%3Ccode%3Eformat_args!%3C/code%3E http://static.rust-lang.org/doc/master/std/macros/macro.println.html http://static.rust-lang.org/doc/master/std/macros/builtin/macro.format_args.html rust类c语言,使用大括号界定代码块,包括选择/循环结构。函数调用myfunc(arg1,arg2).运算符和c的一样,优先级也基本相同。注视也一样,模块名通过两个冒号分离,像c++. if和while的括号不是必须的,他们的结构体必须在大括号里边,单条语句也不行。。 let关键字定义一个局部变量,变量默认是不可变的。需要改变的变量用let mut定义。 rust可以推断局部变量的类型,你可以在let后面加一个冒号,并指定变量的类型。常量的声明必须跟有变量类型。 static MONSTER_FACTOR: f64 = 57.8; let monster_size = MONSTER_FACTOR * 10.0; let monster_size: int = 50; 上边代码回产生一个变量未使用的警告,可以在变量名前加下划线屏蔽警告。 static声明Static items(constant value),可以被全局使用。rust的标示符以字母或者下划线开头,后面跟字母数字下划线。函数,变量,模块名用小写字母,使用下划线分割。定义的类型名用驼峰命名方式,rust原始类型名是小写。
let my_variable = 100;
type MyType = int;
let price;
if item == "salad" {
    price = 3.50;
} else if item == "muffin" {
    price = 2.25;
} else {
    price = 2.00;
}
let price =
    if item == "salad" {
        3.50
    } else if item == "muffin" {
        2.25
    } else {
        2.00
    };
上面两种写法相同,第二种最后有一个分号。大括号里的最后一行代码没有分号的话,他的值将作为整个表达式的值。 所以上面第二种写法,分支里边的数值不能加分号,加上的话回返回()或者空。 rust中除声明(变量,函数,traits, enum types),都是表达式。
fn is_four(x: int) -> bool {
   x == 4
}
不需要写return,表达式的结果将作为结果返回。 整型:int uint,分为8位,16位,32位,64位。数后面跟的字符代表类型i for int, u for uint, i8 for the i8,如果不跟,默认当做int类型 浮点: f32,f64。浮点数可以写成:0.0, 1e6, or 2.1e-4。 bool:true,false char: 单引号,类c 原始字符串,不包含转义:r"" 操作符类c,as操作符将左边的数值转换成右边的类型。as只能用于基本的数字类型和指针,不支持重载。transmute  

Continue

不定义的话默认差不多有一分钟,具体不知道 一种方法:engine = sqlalchemy.create_engine(db_connect_str, connect_args={'connect_timeout': 10}) 还可以直接写到db_connect_str后边,connect_args就是连接字符串后面跟的参数。

"mysql://user:password@host/test?connect_timeout=1"

Continue