基于Predictive Parsing的ABNF语法分析器(五)——AbnfParser文法解析器之单字符的情形(如HTAB、LF、CR、SP)

本文介绍基于Predictive Parsing的ABNF语法分析器中,针对单字符如HTAB、LF、CR、SP的解析实现,这些函数在匹配时无需前瞻。同时,补充了VCHAR方法,该方法验证字符是否在0x21-0x7E范围内。文章还提及了相关的单元测试和系列文章索引。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先来看看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: 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/>.
 */

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

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

    }


补充多一个方法VCHAR(),这个方法很简单,就是只要输入字符在0x21-7E之间就算是匹配,返回相应的字符(串):

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

//  VCHAR          =  %x21-7E
	protected String VCHAR() throws IOException, MatchException {
        assertMatch(is.peek(), 0x21, 0x7E);
        int value = is.read();
        return String.valueOf((char)value);
	}

    //  VCHAR          =  %x21-7E
    @Test
    public void testVCHAR() throws Exception {
        Tester<String> tester = new Tester() {
            public String test(AbnfParser parser) throws MatchException, IOException {
                return parser.VCHAR();
            }
        };

        Assert.assertEquals(String.valueOf((char)0x21), AbnfParserFactory.newInstance(new char[] {0x21}).VCHAR());
        Assert.assertEquals(String.valueOf((char)0x22), AbnfParserFactory.newInstance(new char[] {0x22}).VCHAR());
        Assert.assertEquals(String.valueOf((char)0x7E), AbnfParserFactory.newInstance(new char[] {0x7E}).VCHAR());
        Assert.assertEquals("B", AbnfParserFactory.newInstance("B").VCHAR());
        Assertion.assertMatchException("", tester, 1, 1);
        Assertion.assertMatchException(" ", tester, 1, 1);
        Assertion.assertMatchException("" + (char)0x7F, tester, 1, 1);
    }

本系列文章索引:基于预测的ABNF文法分析器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值