Skip to content

chai2010/wc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


基于flex实现的wc命令, 单词计数

创建wc.h文件, 包含要统计的变量和yylex词法解析函数:

extern int chars;
extern int words;
extern int lines;

创建wc.c文件, 保护变量的定义并初始化为0值:

#include "wc.h"

int chars = 0;
int words = 0;
int lines = 0;

最重要的词法分析函数的实现由flex工具生成:

extern int yylex(void);

创建wc.l文件:

%option noyywrap

%{
#include "wc.h"
%}

%%

[a-zA-Z]+ { words++; chars += strlen(yytext); }
\n        { chars++; lines++; }
.         { chars++; }

%%

通过以下命令生成lex.yy.c文件(其中包含yylex函数的实现):

$ flex --prefix=yy --header-file=lex.yy.h wc.l

然后在Go语言中调用词法分析器并输出结果:

package main

//#include "lex.yy.h"
//#include "wc.h"
import "C"
import "fmt"

func main() {
	C.yylex()
	fmt.Printf("%8d%8d%8d\n", C.lines, C.words, C.chars)
}

通过以下的命令运行:

$ cat wc.l | go run .
      19      47     355

改进: 从内存读取数据

flex生成的代码导出了yyinyyout全局变量,可以用于指定打开的输入流文件(否则从标准输入读取):

extern FILE *yyin, *yyout;
``

不过以上的是C语言文件接口在Go语言中使用比较麻烦此外flex还生成了以下三个函数:

```c
YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len  );

然后调整Go语言函数:

package main

//#include "lex.yy.h"
//#include "wc.h"
import "C"
import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
)

var (
	flagInput = flag.String("f", "", "set input file")
)

func main() {
	flag.Parse()

	var (
		content []byte
		err     error
	)

	if *flagInput == "" {
		// cat wc.go | go run .
		content, err = ioutil.ReadAll(os.Stdin)
		if err != nil {
			log.Fatal(err)
		}
	} else {
		// go run . -f wc.go
		content, err = ioutil.ReadFile(*flagInput)
		if err != nil {
			log.Fatal(err)
		}
	}

	C.yy_scan_bytes(
		(*C.char)(C.CBytes(content)),
		C.yy_size_t(len(content)),
	)
	C.yylex()

	fmt.Printf("%8d%8d%8d\n", C.lines, C.words, C.chars)
}

在调用C.yylex函数之前调用C.yy_scan_bytes函数用Go语言的切片初始化词法扫描的缓冲区。

About

基于flex实现的wc命令, 单词计数

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages