我们来看看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. Tomcat与web程序结构与Http协议

    telnet 一:打开telnet服务: 控制面板------> 程序和功能---> 打开或关闭windows功能---> 选中 Telnet客户端--->确定 二:测试tel ...

  2. Ubuntu 安装启动Tomcat

    首先下载ubuntu 的tar包 官网: http://tomcat.apache.org/download-80.cgi 安装启动 1 .下载对应的tar 2 .解压任意文件夹下,更改名字tomca ...

  3. 前端面试题整理(js)

    1.HTTP协议的状态消息都有哪些? HTTP状态码是什么: Web服务器用来告诉客户端,发生了什么事. 状态码分类: 1**:信息提示.请求收到,继续处理2**:成功.操作成功收到,分析.接受3** ...

  4. 深入浅出 消息队列 ActiveMQ(转)

    一. 概述与介绍 ActiveMQ 是Apache出品,最流行的.功能强大的即时通讯和集成模式的开源服务器.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provide ...

  5. CentOS下利用sshpass不用手动输入密码远程执行命令

       在测试的时候要同时操作多台机器,每次都要挨个去执行几乎相同的命令或者修改一些设置,这样很影响工作效率也很烦,所以就想写一个脚本,远程自动去做这些操作.远程执行命令很简单,但是不能在执行命令加上命 ...

  6. swap函數 进阶探讨与实现

    相信以下這個C程序非常多人都見過啦.當時自己看 美少女战士谭浩强 写的那本书上的解释.反正我当时是没看太懂详细是什么意思.谱架啊~~~ #include <stdio.h> void sw ...

  7. 关于自动刷新CSS

    由于最近系统调整大量的css,希望用户在浏览的时候能即时看到css的更改,而不是继续看到的是客户机上的缓存css. 在网络上找了下,发现很多人推荐一个叫cssrefresh的小工具. http://w ...

  8. 点击得到QTableWidget中任意位置QPushButton的行列信息

    http://www.qtcn.org/bbs/read-htm-tid-51835.html http://www.qtcn.org/bbs/simple/?t43841.html 比如(点击每行最 ...

  9. delphi程序设计之底层原理(有些深度)

    虽然用delphi也有7,8年了,但大部分时间还是用在系统的架构上,对delphi底层还是一知半解,今天在网上看到一篇文章写得很好,虽然是07年的,但仍有借鉴的价值. 现摘录如下: Delphi程序设 ...

  10. 将 Shiro 作为一个许可为基础的应用程序 五:password加密/解密Spring应用

    考虑系统password的安全,眼下大多数系统都不会把password以明文的形式存放到数据库中. 一把会採取下面几种方式对password进行处理 password的存储 "编码" ...