先来看看AbnfParser类如何对ABNF文法中最简单的一些单字节符号如何进行解析,这些单字节符号包括跳格、换行、回车和空格:
/* 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: [email protected]) 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/>. */ // HTAB = %x09 protected String HTAB() throws IOException, MatchException { // 断言下一个字符为0x09(否则抛出MatchException异常) assertMatch(is.peek(), 0x09); int value = is.read(); // 返回HTAB的字符串值 return String.valueOf((char)value); } // LF = %x0A protected String LF() throws IOException, MatchException { // 断言下一个字符为0x0A(否则抛出MatchException异常) assertMatch(is.peek(), 0x0A); int value = is.read(); // 返回换行的字符串值 return String.valueOf((char)value); } // CR = %x0D protected String CR() throws IOException, MatchException { // 断言下一个字符为0x0D(否则抛出MatchException异常) assertMatch(is.peek(), 0x0D); int value = is.read(); // 返回回车的字符串值 return String.valueOf((char)value); } // SP = %x20 protected String SP() throws IOException, MatchException { // 断言下一个字符为0x20(否则抛出MatchException异常) assertMatch(is.peek(), 0x20); int value = is.read(); // 返回空格的字符串值 return String.valueOf((char)value); }
这些单字符的解析函数不需要向前看(预测),因为当他们一旦被调用,就意味着必须是相应的字符,否则就是抛出异常了。
接下来看看上面各个函数对应的单元测试函数。
/* 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: [email protected]) 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/>. */ // HTAB = %x09 @Test public void testHTAB() throws Exception { Tester<String> tester = new Tester<String>() { @Override public String test(AbnfParser parser) throws MatchException, IOException { // 测试器负责调用被测函数AbnfParser.HTAB() return parser.HTAB(); } }; // 测试用例1:一个0x09字符输入的情形 Assert.assertEquals(String.valueOf((char)0x09), AbnfParserFactory.newInstance(new char[] {0x09}).HTAB()); // 测试用例2:两个0x09字符输入的情形 Assert.assertEquals(String.valueOf((char) 0x09), AbnfParserFactory.newInstance(new char[]{0x09, 0x09}).HTAB()); // 测试用例3:一个0x0D字符输入的情形(异常) Assertion.assertMatchException("" + (char) 0x0D, tester, 1, 1); // 测试用例3:空字符输入的情形(异常) Assertion.assertMatchException("", tester, 1, 1); } // LF = %x0A @Test public void testLF() throws Exception { Tester<String> tester = new Tester<String>() { @Override public String test(AbnfParser parser) throws MatchException, IOException { // 测试器负责调用被测函数AbnfParser.LF() return parser.LF(); } }; // 测试用例1:一个0x0A字符输入的情形 Assert.assertEquals(String.valueOf((char)0x0A), AbnfParserFactory.newInstance(new char[] {0x0A}).LF()); // 测试用例2:两个0x0A字符输入的情形 Assert.assertEquals(String.valueOf((char) 0x0A), AbnfParserFactory.newInstance(new char[]{0x0A, 0x0A}).LF()); // 测试用例3:一个0x0D字符输入的情形(异常) Assertion.assertMatchException("", tester, 1, 1); // 测试用例3:空字符输入的情形(异常) Assertion.assertMatchException("" + (char)0x0D, tester, 1, 1); } // CR = %x0D @Test public void testCR() throws Exception { Tester<String> tester = new Tester<String>() { @Override public String test(AbnfParser parser) throws MatchException, IOException { return parser.CR(); } }; Assert.assertEquals(String.valueOf((char) 0x0D), AbnfParserFactory.newInstance(new char[]{0x0D, 0x0D}).CR()); Assertion.assertMatchException("", tester, 1, 1); Assertion.assertMatchException("" + (char)0x0A, tester, 1, 1); } // SP = %x20 @Test public void testSP() throws Exception { Tester<String> tester = new Tester<String>() { @Override public String test(AbnfParser parser) throws MatchException, IOException { return parser.SP(); } }; Assert.assertEquals(String.valueOf((char)0x20), AbnfParserFactory.newInstance(new char[] {0x20, 0x20}).SP()); Assertion.assertMatchException("", tester, 1, 1); Assertion.assertMatchException("" + (char)0x0D, tester, 1, 1); }