基于Predictive Parsing的ABNF语法分析器(六)——AbnfParser文法解析器之多个符号连接的情形(如rule和CRLF)

基于预测的文法分析器,一个明显的特点就是将非终结符定义为解析函数(方法),当非终结符号可以派生为其他非终结符号时,在解析函数中递归调用即可。这种方法的一个缺点,是难以处理需要回溯的情形,后面我们再详细分析。上次我们研究了诸如CR、LF、HTAB等单个字符的解析,这一篇来看看稍微复杂一点的多个符号连接的情形,包括CRLF和RULE两个符号。

/*

    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/>.

 */



//  CRLF           =  CR LF

	protected String CRLF() throws IOException, MatchException {      

//      回车和换行符号,直接调用相应的CR、LF方法来进行解析就OK。

		return CR() + LF();

	}



    //  CRLF           =  CR LF

    @Test

//  测试CRLF方法的单元测试方法

    public void testCRLF() throws Exception {

//  创建一个测试器,在测试器的test方法中调用被测方法CRLF()

        Tester<String> tester = new Tester<String>() {

            @Override

            public String test(AbnfParser parser) throws MatchException, IOException {

                return parser.CRLF();

            }

        };

//      对于字符串0x0D + 0x0A,断言解析成功

        Assert.assertEquals(String.valueOf((char)0x0D) + String.valueOf((char)0x0A), AbnfParserFactory.newInstance(new char[] {0x0D, 0x0A}).CRLF());



//      对于字符串0x0D + 0x0A + 0x0C,断言解析成功,但最后面的0x0C不应该被解析。

        Assert.assertEquals(String.valueOf((char)0x0D) + String.valueOf((char)0x0A), AbnfParserFactory.newInstance(new char[] {0x0D, 0x0A, 0x0C}).CRLF());

//      对于字符串0x0D + 0x0A + 0x0D,断言解析成功,但最后面的0x0D不应该被解析。

        Assert.assertEquals(String.valueOf((char)0x0D) + String.valueOf((char)0x0A), AbnfParserFactory.newInstance(new char[] {0x0D, 0x0A, 0x0D}).CRLF());

//      对于字符串0x0D + 0x0A + 0x0A,断言解析成功,但最后面的0x0A不应该被解析。

        Assert.assertEquals(String.valueOf((char)0x0D) + String.valueOf((char)0x0A), AbnfParserFactory.newInstance(new char[] {0x0D, 0x0A, 0x0A}).CRLF());

//      对于空字符串0x0D + 0x0A + 0x0C,断言解析异常

        Assertion.assertMatchException("", tester, 1, 1);

//      对于字符串0x0D,断言解析异常

        Assertion.assertMatchException("" + (char)0x0D, tester, 1, 1);

//      对于字符串0x0A,断言解析异常

        Assertion.assertMatchException("" + (char)0x0A, tester, 1, 1);

    }



//		        rule           =  rulename defined-as elements c-nl

//      解析rule的方法

	protected Rule rule() throws IOException, MatchException {

//              rule的第一个元素是rulename,首先调用rulename()方法,并记录解析到的规则名

		RuleName rulename = rulename();



//              rulename后面紧接着defined-as元素,调用相应的方法

		String definedAs = defined_as();



//              defined-as后面接着elements元素,调用elements()

		Elements elements = elements();



//              elements后面接着c-nl元素,调用之。

		c_nl();



//              返回解析到的规则

		return new Rule(rulename, definedAs, elements);

	}



    //		        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();

//      a=b是一条符合文法的规则

        Assertion.assertMatch("a=b" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=", elements), 1, 2);



//      a=/b是一条符合文法的规则

        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();



//      a=b c d是一条符合文法的规则

        Assertion.assertMatch("a=b c d" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=", elements), 1, 2);



//      a=/b c d是一条符合文法的规则

        Assertion.assertMatch("a=/b c d" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=/", elements), 1, 2);



        elements = AbnfParserFactory.newInstance("[b]").elements();



//      a=[b]是一条符合文法的规则

        Assertion.assertMatch("a=[b]" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=", elements), 1, 2);



//      a=/[b]是一条符合文法的规则

        Assertion.assertMatch("a=/[b]" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=/", elements), 1, 2);



        elements = AbnfParserFactory.newInstance("*b").elements();



//      a=*b是一条符合文法的规则

        Assertion.assertMatch("a=*b" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=", elements), 1, 2);



//      a=/*b是一条符合文法的规则

        Assertion.assertMatch("a=/*b" + (char)0x0D + (char)0x0A, tester, new Rule(new RuleName("a"), "=/", elements), 1, 2);

    }

下一篇我们将分析更复杂的文法。

你可能感兴趣的:(parser)