jcpp : C 预编译器的 java 实现

http://www.anarres.org/projects/jcpp/

JCPP - A Java C Preprocessor
Introduction

The C Preprocessor is an interesting standard. It appears to be derived from the de-facto behaviour of the first preprocessors, and has evolved over the years. Implementation is therefore difficult. JCPP is a complete, compliant, standalone, pure Java implementation of the C preprocessor. It is intended to be of use to people writing C-style compilers in Java using tools like sablecc, antlr, JLex, CUP and so forth. This project has has been used to successfully preprocess much of the source code of the GNU C library. As of version 1.2.5, it can also preprocess the Apple Objective C library.

The license is Apache-2.0. Versions prior to 1.2.2 were licensed under GPL-2.0, but on the basis of representations received, the license has now changed. Subversion access is available on request. Less restrictive licenses are freely available on request, but please ask, because I want people to use this software, but I'm curious to know who is using it and for what purpose.


=================================================
jcpp : C 预编译器的 java 实现。

=================================================

代码中使用了模板。通过 vpp 任务将模板生成源代码的。

JCpp\etc\targets\global-vpp.xml
<vppcopy todir="${global.dir.build.java}">
<fileset dir="${global.dir.src.java}">
<include name="**/*.java" />
</fileset>

=================================================

通过 ant 编译后,build\java 目录下的代码是普通的 java 代码。

=================================================

程序运行后,可进行 c 语言预处理。如:
>#define aa 2
>aa

将输出 2。

=================================================
org/anarres/cpp/Main.java
if (g.getOptind() == args.length)
pp.addInput(new InputLexerSource(System.in));

通过这两行,将 System.in 做为输入。

=================================================
语法分析的代码在 LexerSource.java


public Token token()
throws IOException,
LexerException {
Token tok = null;

int _l = line;
int _c = column;

int c = read();
int d;

switch (c) {
case '\n':
//throw new RuntimeException("token() 582");
//System.out.println("token() 582");
if (ppvalid) {
bol = true;
if (include) {
tok = new Token(NL, _l, _c, "\n");
}
else {
int nls = 0;
do {
nls++;
d = read();
} while (d == '\n');
unread(d);
char[] text = new char[nls];
for (int i = 0; i < text.length; i++)
text[i] = '\n';
// Skip the bol = false below.
tok = new Token(NL, _l, _c, new String(text));
}
if (DEBUG)
System.out.println("lx: Returning NL: " + tok);
return tok;
}
/* Let it be handled as whitespace. */
break;

case '!':
tok = cond('=', NE, '!');
break;

case '#':
//System.out.println("token() 613");
if (bol)
tok = new Token(HASH);
else
tok = cond('#', PASTE, '#');
break;

case '+':
d = read();
if (d == '+')
tok = new Token(INC);
else if (d == '=')
tok = new Token(PLUS_EQ);
else
unread(d);
break;
case '-':
d = read();
if (d == '-')
tok = new Token(DEC);
else if (d == '=')
tok = new Token(SUB_EQ);
else if (d == '>')
tok = new Token(ARROW);
else
unread(d);
break;

case '*':
tok = cond('=', MULT_EQ, '*');
break;
case '/':
d = read();
if (d == '*')
tok = ccomment();
else if (d == '/')
tok = cppcomment();
else if (d == '=')
tok = new Token(DIV_EQ);
else
unread(d);
break;

case '%':
d = read();
if (d == '=')
tok = new Token(MOD_EQ);
else if (digraphs && d == '>')
tok = new Token('}'); // digraph
else if (digraphs && d == ':') PASTE: {
d = read();
if (d != '%') {
unread(d);
tok = new Token('#'); // digraph
break PASTE;
}
d = read();
if (d != ':') {
unread(d); // Unread 2 chars here.
unread('%');
tok = new Token('#'); // digraph
break PASTE;
}
tok = new Token(PASTE); // digraph
}
else
unread(d);
break;

case ':':
/* :: */
d = read();
if (digraphs && d == '>')
tok = new Token(']'); // digraph
else
unread(d);
break;

case '<':
if (include) {
tok = string('<', '>');
}
else {
d = read();
if (d == '=')
tok = new Token(LE);
else if (d == '<')
tok = cond('=', LSH_EQ, LSH);
else if (digraphs && d == ':')
tok = new Token('['); // digraph
else if (digraphs && d == '%')
tok = new Token('{'); // digraph
else
unread(d);
}
break;

case '=':
tok = cond('=', EQ, '=');
break;

case '>':
d = read();
if (d == '=')
tok = new Token(GE);
else if (d == '>')
tok = cond('=', RSH_EQ, RSH);
else
unread(d);
break;

case '^':
tok = cond('=', XOR_EQ, '^');
break;

case '|':
d = read();
if (d == '=')
tok = new Token(OR_EQ);
else if (d == '|')
tok = cond('=', LOR_EQ, LOR);
else
unread(d);
break;
case '&':
d = read();
if (d == '&')
tok = cond('=', LAND_EQ, LAND);
else if (d == '=')
tok = new Token(AND_EQ);
else
unread(d);
break;

case '.':
d = read();
if (d == '.')
tok = cond('.', ELLIPSIS, RANGE);
else
unread(d);
/* XXX decimal fraction */
break;

case '0':
/* octal or hex */
d = read();
if (d == 'x' || d == 'X')
tok = number_hex((char)d);
else {
unread(d);
tok = number_octal();
}
break;

case '\'':
tok = character();
break;

case '"':
tok = string('"', '"');
break;

case -1:
close();
tok = new Token(EOF, _l, _c, "<eof>");
break;
}

if (tok == null) {
if (Character.isWhitespace(c)) {
tok = whitespace(c);
}
else if (Character.isDigit(c)) {
tok = number_decimal(c);
}
else if (Character.isJavaIdentifierStart(c)) {
tok = identifier(c);
}
else {
tok = new Token(c);
}
}

if (bol) {
switch (tok.getType()) {
case WHITESPACE:
case CCOMMENT:
break;
default:
bol = false;
break;
}
}

tok.setLocation(_l, _c);
if (DEBUG)
System.out.println("lx: Returning " + tok);
// (new Exception("here")).printStackTrace(System.out);
return tok;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值