在实现oz的路上迈出第一步(避免被认为是死了)

既是指项目,也是指人。

刚刚将所有的提交合并到主分支上,现在代码仓库的语言条变得五颜六色了起来。唔,标准的程序员浪漫么。

首先是有关Makefile的奇技淫巧。Makefile的隐式规则处理lex足够了,但是它不会自动生成yacc的头文件y.tab.h,导致了lex规则中不能用token之类的宏和变量。因此要做三件事:

  1. 手动添加yacc的参数-d,确保生成头文件
  2. 确保yacc的规则在lex的规则之前被处理生成
  3. 由于修改了Makefile规则,原来的自动删除中间文件现在没有了,要手动删除

最后的成果大概是这样:

1
2
3
4
5
6
7
8
9
10
all: main
cp main oz
main: lexical.o grammer.o
lexical.o: grammer.c
grammer.c: YFLAGS += -d
.PHONY: clean
clean:
rm *.o *.tab.h grammer.c main

其中复制的一步是为了避免重复链接oz(同时还要用隐式规则),又希望上一级的Makefile看到的名字是oz而不是main。没有刻意保持目录的整洁,很多东西留到了clean里面才删,等项目大一些了要考虑重写一下。


lex的规则有点奇怪。写成如下这样:

1
" "{OPERATOR_CHARSET1}+/("("|[0-9]) { /* ... */ }

而不是后面括号当中部分的分配率展开形式可以避免报错如下:

1
2
lexical.l:66: warning, trailing context made variable due to preceding '|' action
lexical.l:66: warning, dangerous trailing context

(也许)也能避免一些解析错误。原因未知。