我们来看看rulelist,它是整个ABNF文法的入口,就是说一个ABNF文法就是一个规则列表rulelist。一个rulelist由若干个rule规则组成,每个rule由规则名rulename、定义方式define-as和元素elements构成。

先来看解析代码:

/*
This file is one of the component a Context-free Grammar Parser Generator,
which accept a piece of text as the input, and generates a parser
for the inputted context-free grammar.
Copyright (C) 2013, Junbiao Pan (Email: panjunbiao@gmail.com) This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version. This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ public class AbnfParser {
// rulelist = 1*( rule / (*c-wsp c-nl) )
protected List<Rule> rulelist() throws IOException, MatchException, CollisionException {
Map<RuleName, Rule> ruleMap = new HashMap<RuleName, Rule>();
List<Rule> ruleList = new ArrayList<Rule>();
// 如果前向字符是字母、空格、分号、回车,则认为是rule、c-wsp或者c-nl
while (match(is.peek(), 0x41, 0x5A) || match(is.peek(), 0x61, 0x7A) || match(is.peek(), 0x20) || match(is.peek(), ';') || match(is.peek(), 0x0D)) {
// 如果是字母开头,则认为是rule,否则是c-wsp或者c-nl
if (match(is.peek(), 0x41, 0x5A) || match(is.peek(), 0x61, 0x7A)) {
// 解析一条规则
Rule rule = rule();
// 判断该条规则是否已经有有定义
if (null == ruleMap.get(rule.getRuleName())) {
// 如果没有定义则放入规则列表
ruleMap.put(rule.getRuleName(), rule);
ruleList.add(rule);
} else {
// 已有定义,则检查定义方式是否为增量定义
Rule defined = ruleMap.get(rule.getRuleName());
if ("=".equals(rule.getDefinedAs()) && "=".equals(defined.getDefinedAs())) {
// 如果不是增量定义,则抛出重复定义异常
throw new CollisionException(rule.getRuleName().toString() + " is redefined.", is.getPos(), is.getLine());
}
// 如果是增量定义则合并两条规则
if ("=".equals(rule.getDefinedAs())) defined.setDefinedAs("=");
defined.getElements().getAlternation().getConcatenations().addAll(rule.getElements().getAlternation().getConcatenations());
}
} else {
// 空格、分号、回车,则是c_wsp
while (match(is.peek(), 0x20) || match(is.peek(), ';') || match(is.peek(), 0x0D)) {
c_wsp();
}
c_nl();
}
}
return ruleList;
} // rulename = ALPHA *(ALPHA / DIGIT / "-")
protected RuleName rulename() throws IOException, MatchException {
// ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
// DIGIT = %x30-39
// 规则名的第一个字符必须是字母
if (!(match(is.peek(), 0x41, 0x5A) || match(is.peek(), 0x61, 0x7A))) {
throw new MatchException("'A'-'Z'/'a'-'z'", is.peek(), is.getPos(), is.getLine());
}
String rulename = "";
rulename += (char)is.read();
// 规则名的后续字符可以是字母、数字、破折号
while (match(is.peek(), 0x41, 0x5A) || match(is.peek(), 0x61, 0x7A) || match(is.peek(), 0x30, 0x39) |match(is.peek(), '-')) {
rulename += (char)is.read();
}
return new RuleName(prefix, rulename);
} // defined-as = *c-wsp ("=" / "=/") *c-wsp
protected String defined_as() throws IOException, MatchException {
String value = "";
// 等号前面的空格
while (match(is.peek(), 0x20) || match(is.peek(), 0x09) || match(is.peek(), ';') || match(is.peek(), (char)0x0D)) {
c_wsp();
}
// 等号
assertMatch(is.peek(), '=');
value = String.valueOf((char)is.read());
// 是否增量定义
if (match(is.peek(), '/')) {
value += (char)is.read();
}
// 等号后面的空格
while (match(is.peek(), 0x20) || match(is.peek(), 0x09) || match(is.peek(), ';') || match(is.peek(), (char)0x0D)) {
c_wsp();
}
return value;
} // elements = alternation *c-wsp
protected Elements elements() throws IOException, MatchException {
// 元素elements其实就是alternation再接着若干空格
Alternation alternation = alternation();
while (match(is.peek(), 0x20) || match(is.peek(), 0x09) || match(is.peek(), ';')) {
c_wsp();
}
return new Elements(alternation);
}
}

单元测试就不罗嗦了,直接看代码。

/*
This file is one of the component a Context-free Grammar Parser Generator,
which accept a piece of text as the input, and generates a parser
for the inputted context-free grammar.
Copyright (C) 2013, Junbiao Pan (Email: panjunbiao@gmail.com) This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version. This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ // rulename = ALPHA *(ALPHA / DIGIT / "-")
@Test
public void testRulename() throws Exception {
Tester<String> tester = new Tester<String>() {
public String test(AbnfParser parser) throws MatchException, IOException {
return parser.rulename().toString();
}
}; // 用各种奇怪的情形来虐
Assert.assertEquals("A", AbnfParserFactory.newInstance("A").rulename().toString());
Assert.assertEquals("a", AbnfParserFactory.newInstance("a").rulename().toString());
Assert.assertEquals("Z", AbnfParserFactory.newInstance("Z").rulename().toString());
Assert.assertEquals("z", AbnfParserFactory.newInstance("z").rulename().toString());
Assert.assertEquals("ABCDEFGHIJKLMNOPQRSTUVWXYZ", AbnfParserFactory.newInstance("ABCDEFGHIJKLMNOPQRSTUVWXYZ").rulename().toString());
Assert.assertEquals("abcdefghijklmnopqrstuvwxyz", AbnfParserFactory.newInstance("abcdefghijklmnopqrstuvwxyz").rulename().toString());
Assert.assertEquals("AbCdEfGhIjKlMnOpQrStUvWxYz", AbnfParserFactory.newInstance("AbCdEfGhIjKlMnOpQrStUvWxYz").rulename().toString());
Assert.assertEquals("aBcDeFgHiJkLmNoPqRsTuVwXyZ", AbnfParserFactory.newInstance("aBcDeFgHiJkLmNoPqRsTuVwXyZ").rulename().toString());
Assert.assertEquals("A1234567890Z", AbnfParserFactory.newInstance("A1234567890Z").rulename().toString());
Assert.assertEquals("a1234567890z", AbnfParserFactory.newInstance("a1234567890z").rulename().toString());
Assert.assertEquals("A1B2C3D4e5f6g7h8i9j0", AbnfParserFactory.newInstance("A1B2C3D4e5f6g7h8i9j0").rulename().toString());
Assert.assertEquals("A1B2C3D4e5f6g7h8i9j0aBcDeFgHiJkLmNoPqRsTuVwXyZAbCdEfGhIjKlMnOpQrStUvWxYz", AbnfParserFactory.newInstance("A1B2C3D4e5f6g7h8i9j0aBcDeFgHiJkLmNoPqRsTuVwXyZAbCdEfGhIjKlMnOpQrStUvWxYz").rulename().toString());
Assert.assertEquals("A1b2C3-4d-", AbnfParserFactory.newInstance("A1b2C3-4d-").rulename().toString());
Assert.assertEquals("a-------------", AbnfParserFactory.newInstance("a-------------").rulename().toString());
Assert.assertEquals("A1b2C3-4d-", AbnfParserFactory.newInstance("A1b2C3-4d-#").rulename().toString());
Assert.assertEquals("A1b2C3-4d-", AbnfParserFactory.newInstance("A1b2C3-4d-..").rulename().toString());
Assert.assertEquals("RFC3261-A1b2C3-4d-", AbnfParserFactory.newInstance("RFC3261-", "A1b2C3-4d-*&^").rulename().toString());
Assertion.assertMatchException("1", tester, 1, 1);
Assertion.assertMatchException("1234567890", tester, 1, 1);
Assertion.assertMatchException("-", tester, 1, 1);
Assertion.assertMatchException("-----------", tester, 1, 1);
Assertion.assertMatchException("#", tester, 1, 1);
Assertion.assertMatchException(".", tester, 1, 1);
Assertion.assertMatchException("~", tester, 1, 1);
Assertion.assertMatchException(")", tester, 1, 1);
Assertion.assertMatchException("", tester, 1, 1);
} // rulelist = 1*( rule / (*c-wsp c-nl) )
@Test
public void testRulelist() throws Exception {
Tester<List<Rule>> tester = new Tester<List<Rule>>() {
@Override
public List<Rule> test(AbnfParser parser) throws MatchException, IOException, CollisionException {
return parser.rulelist();
}
}; String input, rulesInput = "";
input = "a=b" + (char)0x0d + (char)0x0a;
rulesInput += input;
List<Rule> rules = new ArrayList<Rule>();
rules.add(AbnfParserFactory.newInstance(input).rule());
input = "b=*c" + (char)0x0d + (char)0x0a;
rulesInput += input;
rules.add(AbnfParserFactory.newInstance(input).rule());
input = "c=[d]" + (char)0x0d + (char)0x0a;
rulesInput += input;
rules.add(AbnfParserFactory.newInstance(input).rule());
input = "d=a/b/c/e" + (char)0x0d + (char)0x0a;
rulesInput += input;
rules.add(AbnfParserFactory.newInstance(input).rule());
input = "e=f/(g h)" + (char)0x0d + (char)0x0a;
rulesInput += input;
rules.add(AbnfParserFactory.newInstance(input).rule());
input = "g=i [j]" + (char)0x0d + (char)0x0a;
rulesInput += input;
rules.add(AbnfParserFactory.newInstance(input).rule());
input = "j=<abcd#1234>" + (char)0x0d + (char)0x0a;
rulesInput += input;
rules.add(AbnfParserFactory.newInstance(input).rule());
input = "j=/\"abcd#1234\"" + (char)0x0d + (char)0x0a;
rulesInput += input;
rules.add(AbnfParserFactory.newInstance(input).rule());
Assertion.assertMatch(rulesInput, tester, AbnfParserFactory.newInstance(rulesInput).rulelist(), 1, 9); } // rule = rulename defined-as elements c-nl
@Test
public void testRule() throws Exception {
Tester<Rule> tester = new Tester<Rule>() {
@Override
public Rule test(AbnfParser parser) throws MatchException, IOException {
return parser.rule();
}
}; String input;
Elements elements;
elements = AbnfParserFactory.newInstance("b").elements();
Assertion.assertMatch("a=b" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=", elements), 1, 2);
Assertion.assertMatch("a=/b" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=/", elements), 1, 2); elements = AbnfParserFactory.newInstance("b/c").elements();
Assertion.assertMatch("a=b/c" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=", elements), 1, 2);
Assertion.assertMatch("a=/b/c" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=/", elements), 1, 2); elements = AbnfParserFactory.newInstance("b c d").elements();
Assertion.assertMatch("a=b c d" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=", elements), 1, 2);
Assertion.assertMatch("a=/b c d" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=/", elements), 1, 2); elements = AbnfParserFactory.newInstance("[b]").elements();
Assertion.assertMatch("a=[b]" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=", elements), 1, 2);
Assertion.assertMatch("a=/[b]" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=/", elements), 1, 2); elements = AbnfParserFactory.newInstance("*b").elements();
Assertion.assertMatch("a=*b" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=", elements), 1, 2);
Assertion.assertMatch("a=/*b" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=/", elements), 1, 2);
} //WSP = SP / HTAB
// VCHAR = %x21-7E
// comment = ";" *(WSP / VCHAR) CRLF
// c-nl = comment / CRLF
// c-wsp = WSP / (c-nl WSP)
// defined-as = *c-wsp ("=" / "=/") *c-wsp
@Test
public void testDefined_as() throws Exception {
Tester<String> tester = new Tester() {
public String test(AbnfParser parser) throws MatchException, IOException {
return parser.defined_as();
}
}; Assertion.assertMatchException("", tester, 1, 1);
Assertion.assertMatch("=", tester, "=", 2, 1);
Assertion.assertMatchException("/", tester, 1, 1);
Assertion.assertMatch("=A", tester, "=", 2, 1);
Assertion.assertMatchException("A=", tester, 1, 1);
Assertion.assertMatch("=/", tester, "=/", 3, 1);
Assertion.assertMatchException(".=/", tester, 1, 1);
Assertion.assertMatch("=/#", tester, "=/", 3, 1);
Assertion.assertMatchException("#=/", tester, 1, 1);
Assertion.assertMatch(" = ", tester, "=", 10, 1);
Assertion.assertMatch(" = =", tester, "=", 10, 1);
Assertion.assertMatch(" =/ ", tester, "=/", 11, 1);
Assertion.assertMatch(" =/ 3", tester, "=/", 11, 1);
Assertion.assertMatch("" + (char)0x0D + (char)0x0A +" " + "=", tester, "=", 3, 2);
Assertion.assertMatchException("" + (char)0x0D + (char)0x0A + "=", tester, 1, 2);
Assertion.assertMatch("" + (char) 0x0D + (char) 0x0A + " " + "==", tester, 3, 2); // Can not handle following case
// TODO
System.out.println("***************************");
Assertion.assertMatchException("" + (char) 0x0D + (char) 0x0A + " " + "=;", tester, 4, 2);
Assertion.assertMatch("" + (char)0x0D + (char)0x0A +" " + "=" + (char)0x0D + (char)0x0A +" ", tester, "=", 2, 3); // Can not handle following case
// TODO
Assertion.assertMatchException("" + (char) 0x0D + (char) 0x0A + " " + "=" + (char) 0x0D + (char) 0x0A, tester, 1, 3); Assertion.assertMatch("" + (char)0x0D + (char)0x0A +" " + "=" + (char)0x0D + (char)0x0A +" =", tester, "=", 2, 3);
Assertion.assertMatch("" + (char)0x0D + (char)0x0A +" " + "=/", tester, "=/", 4, 2);
Assertion.assertMatch("" + (char) 0x0D + (char) 0x0A + " " + "=//", tester, "=/", 4, 2);
Assertion.assertMatch("" + (char) 0x0D + (char) 0x0A + " " + "=/" + (char) 0x0D + (char) 0x0A + " ", tester, "=/", 2, 3);
Assertion.assertMatch("" + (char) 0x0D + (char) 0x0A + " " + "=/" + (char) 0x0D + (char) 0x0A + " ==", tester, "=/", 2, 3);
Assertion.assertMatch("" + (char)0x0D + (char)0x0A +(char)0x09 + "=", tester, "=", 3, 2);
Assertion.assertMatch("" + (char)0x0D + (char)0x0A +(char)0x09 + "====", tester, 3, 2);
Assertion.assertMatch("" + (char)0x0D + (char)0x0A +(char)0x09 + "=" + (char)0x0D + (char)0x0A +(char)0x09, tester, "=", 2, 3);
Assertion.assertMatch("" + (char)0x0D + (char)0x0A +(char)0x09 + "=" + (char)0x0D + (char)0x0A +(char)0x09 + "=", tester, "=", 2, 3);
Assertion.assertMatch("" + (char)0x0D + (char)0x0A +(char)0x09 + "=/", tester, "=/", 4, 2);
Assertion.assertMatch("" + (char)0x0D + (char)0x0A +(char)0x09 + "=/=/", tester, "=/", 4, 2);
Assertion.assertMatch("" + (char)0x0D + (char)0x0A +(char)0x09 + "=/" + (char)0x0D + (char)0x0A +(char)0x09, tester, "=/", 2, 3);
Assertion.assertMatch("" + (char)0x0D + (char)0x0A +(char)0x09 + "=/" + (char)0x0D + (char)0x0A +(char)0x09 + "/=/=/", tester, "=/", 2, 3);
Assertion.assertMatch("" + (char)0x0D + (char)0x0A +(char)0x09 + (char)0x0D + (char)0x0A +(char)0x09 + "=", tester, "=", 3, 3);
Assertion.assertMatch("" + (char)0x0D + (char)0x0A +(char)0x09 + (char)0x0D + (char)0x0A +(char)0x09 + "==/=/=/", tester, "=", 3, 3);
Assertion.assertMatch("" + (char)0x0D + (char)0x0A +(char)0x09 + (char)0x0D + (char)0x0A +(char)0x09 + "=" + (char)0x0D + (char)0x0A +(char)0x09 + (char)0x0D + (char)0x0A +(char)0x09, tester, "=", 2, 5);
Assertion.assertMatch("" + (char)0x0D + (char)0x0A +(char)0x09 + (char)0x0D + (char)0x0A +(char)0x09 + "=" + (char)0x0D + (char)0x0A +(char)0x09 + (char)0x0D + (char)0x0A +(char)0x09 + "/", tester, "=", 2, 5);
Assertion.assertMatch("" + (char) 0x0D + (char) 0x0A + (char) 0x09 + (char) 0x0D + (char) 0x0A + (char) 0x09 + "=/", tester, "=/", 4, 3);
Assertion.assertMatch("" + (char) 0x0D + (char) 0x0A + (char) 0x09 + (char) 0x0D + (char) 0x0A + (char) 0x09 + "=/=", tester, "=/", 4, 3);
Assertion.assertMatch("" + (char) 0x0D + (char) 0x0A + (char) 0x09 + (char) 0x0D + (char) 0x0A + (char) 0x09 + "=/" + (char) 0x0D + (char) 0x0A + (char) 0x09 + (char) 0x0D + (char) 0x0A + (char) 0x09, tester, "=/", 2, 5); // Can not handle following case
// TODO
Assertion.assertMatchException(
"" + (char) 0x0D + (char) 0x0A + (char) 0x09 + (char) 0x0D + (char) 0x0A + (char) 0x09
+ "=/" + (char) 0x0D + (char) 0x0A + (char) 0x09 + (char) 0x0D + (char) 0x0A,
tester, 1, 5
); Assertion.assertMatch(
"" + (char) 0x0D + (char) 0x0A + (char) 0x09 + (char) 0x0D + (char) 0x0A + (char) 0x09
+ "=/" + (char) 0x0D + (char) 0x0A + (char) 0x09 + (char) 0x0D + (char) 0x0A + (char) 0x09 + "=",
tester, "=/", 2, 5); Assertion.assertMatch("" + (char)0x09 + (char)0x09 + "=", tester, "=", 4, 1);
Assertion.assertMatch("" + (char)0x09 + (char)0x09 + "==/", tester, "=", 4, 1);
Assertion.assertMatch("" + (char)0x09 + (char)0x09 + "=" + (char)0x09 + (char)0x09, tester, "=", 6, 1);
Assertion.assertMatch("" + (char)0x09 + (char)0x09 + "=/", tester, "=/", 5, 1);
Assertion.assertMatch("" + (char)0x09 + (char)0x09 + "=/=", tester, "=/", 5, 1);
Assertion.assertMatch("" + (char) 0x09 + (char) 0x09 + "=/" + (char) 0x09 + (char) 0x09, tester, "=/", 7, 1);
Assertion.assertMatch("" + (char) 0x09 + (char) 0x09 + "=/" + (char) 0x09 + (char) 0x09 + "=", tester, "=/", 7, 1);
Assertion.assertMatch(
"; ; ; \"" + (char) 0x0D + (char) 0x0A + " " + "=" + "; ; ; \"" + (char) 0x0D + (char) 0x0A + " ",
tester, "=", 2, 3);
Assertion.assertMatch(
"; ; ; \"" + (char)0x0D + (char)0x0A + " " + "=" + "; ; ; \"" + (char)0x0D + (char)0x0A + " /",
tester, "=", 2, 3); Assertion.assertMatch(
"; ; ; \"" + (char) 0x0D + (char) 0x0A + " " + "=/" + "; ; ; \"" + (char) 0x0D + (char) 0x0A + " ",
tester, "=/", 2, 3); Assertion.assertMatch(
"; ; ; \"" + (char)0x0D + (char)0x0A + " " + "=/" + "; ; ; \"" + (char)0x0D + (char)0x0A + " =/",
tester, "=/", 2, 3);
} // elements = alternation *c-wsp
@Test
public void testElements() throws Exception {
Tester<Elements> tester = new Tester<Elements>() {
@Override
public Elements test(AbnfParser parser) throws MatchException, IOException {
return parser.elements();
}
}; String input;
input = "A/B/C";
Assertion.assertMatch(input, tester, AbnfParserFactory.newInstance(input).elements(), 6, 1); // TODO
input = "A/B/C ";
Assertion.assertMatchException(input, tester, 8, 1); }

单元测试里面体现出来的一些算法缺陷,我会写一篇帖子专门总结一下。

到这里,文法解析器就基本完成了,下一篇我会以SIP(RFC3261)协议为例子,生成SIP的ABNF文法表示。

基于Predictive Parsing的ABNF语法分析器(十三)——rulelist、rule、rulename、define-as和elements的更多相关文章

  1. 基于Predictive Parsing的ABNF语法分析器(十)——AbnfParser文法解析器之数值类型(num-val)

    ANBF语法中的数值类型有3种:二进制.十进制和十六进制,可以是一个以点号分隔的数列,也可以是一个数值的范围.例如,%d11.22.33.44.55表示五个有次序的十进制数字“11.22.33.44. ...

  2. 开源语法分析器--ANTLR

      序言 有的时候,我还真是怀疑过上本科时候学的那些原理课究竟是不是在浪费时间.比方学完操作系统原理之后我们并不能自己动手实现一个操作系统:学完数据库原理我们也不能弄出个像样的DBMS出来:相同,学完 ...

  3. C# 语法分析器(二)LR(0) 语法分析

    系列导航 (一)语法分析介绍 (二)LR(0) 语法分析 (三)LALR 语法分析 (四)二义性文法 (五)错误恢复 (六)构造语法分析器 首先,需要介绍下 LALR 语法分析的基础:LR(0) 语法 ...

  4. 编译原理简单语法分析器(first,follow,分析表)源码下载

    编译原理(简单语法分析器下载) http://files.cnblogs.com/files/hujunzheng/%E5%8A%A0%E5%85%A5%E5%90%8C%E6%AD%A5%E7%AC ...

  5. Tiny语法分析器(递归下降分析法实现)

    递归规约规则是这样的 program→stmt-sequence stmt-sequence→stmt-sequence;statement|statement statement→if-stmt|r ...

  6. 有没有好用的开源sql语法分析器? - 匿名用户的回答 - 知乎

    有没有好用的开源sql语法分析器? - 匿名用户的回答 - 知乎 presto,hive,drill,calcite,sparksq

  7. SQLite Lemon 语法分析器学习与使用

    本文是浙江大学出版社的<LEMON语法分析生成器(LALR 1类型)源代码情景分析>学习笔记. 用到的Windows下的编译器介绍MinGW(http://www.mingw.org/): ...

  8. [Swift]LeetCode385. 迷你语法分析器 | Mini Parser

    Given a nested list of integers represented as a string, implement a parser to deserialize it. Each ...

  9. 语法分析器初步学习——LISP语法分析

    语法分析器初步学习——LISP语法分析 本文参考自vczh的<如何手写语法分析器>. LISP的表达式是按照前缀的形式写的,比如(1+2)*(3+4)在LISP中会写成(*(+ 1 2)( ...

随机推荐

  1. [VBS]_[活动分组程序]

    场景: 1.每次搞活动都需要分组,比如20个人分3个组,如何才能更公平的分组,想到的只能是随机分组程序. 2.时间关系并没有实现男女平衡的分组,有时间的哥们可以自己实现. 文件1:分组程序.vbs,记 ...

  2. iOS &quot;The sandbox is not in sync with the Podfile.lock&quot;解决方式

    更新Cocoapod之后出现故障: diff: /../Podfile.lock: No such file or directory diff: Manifest.lock: No such fil ...

  3. asp.net2.0安全性(1)--用户角色篇(代码实现2)--转载来自车老师

    加载所有用户 MembershipUserCollection user = Membership.GetAllUsers(); listUser.DataSource = user; listUse ...

  4. 论文阅读笔记 - YARN : Architecture of Next Generation Apache Hadoop MapReduceFramework

    作者:刘旭晖 Raymond 转载请注明出处 Email:colorant at 163.com BLOG:http://blog.csdn.net/colorant/ 更多论文阅读笔记 http:/ ...

  5. 隐藏AutoCompleteTextView下拉框的滚动条

    最近做项目需要用到AutoCompleteTextView这个控件,而其下拉框的滚动条有点难看,于是想去掉.走了些弯路,终于弄通了. 首先先介绍一种不靠谱的方法:反射机制 为什么会有人想到用这个呢? ...

  6. 使用JDBC获取能自动增加的主键

    本篇讲述如何使用JDBC获取能自动增加的主键的值.有时候我们在向数据库插入数据时希望能返回主键的值,而不是通过查询的方式.一般来说,在多表相互关联主键约束,也就是说别的表的外键约束是该表的主键,那么在 ...

  7. 【Java数据结构】Java数据结构之链表反转

    我们都知道用C可以很简单的实现单链表反转,今天来学习下,在Java中如何实现链表反转. 思路很简单,定义一个类,这个类分成2块,一块是表示自身的标志,另外一个存储指向下一个元素的引用.通过互换相邻两个 ...

  8. 14.6.7?Limits on InnoDB Tables InnoDB 表的限制

    14.6.7?Limits on InnoDB Tables InnoDB 表的限制 警告: 不要把MySQL system tables 从MyISAM 到InnoDB 表. 这是不支持的操作,如果 ...

  9. ORACLE 安装Oracle12遇到的问题

    0.全然卸载Oracle10(Windows) 在Windows下多次安装Oracle会造成混乱.重装Oracle的话一定先要干净卸载曾经的Oracle. 一.有必要时先备份 二.卸载步骤 1.用DB ...

  10. python与其它语言进行比較

    近期python语言貌似比較火, 今天闲来无事,简单的看了下,算是个入门吧.一门语言之所以值得这么多人去学,必然有它的独到之处,以下我们就用python和其它语言做个比較. Pythond VS C# ...