/* * Copyright (C) 2010 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package lombok.ast.grammar; import lombok.ast.Node; import org.parboiled.BaseParser; import org.parboiled.Rule; import org.parboiled.annotations.SuppressSubnodes; public class LiteralsParser extends BaseParser<Node> { final ParserGroup group; final LiteralsActions actions; public LiteralsParser(ParserGroup group) { this.actions = new LiteralsActions(group.getSource()); this.group = group; } public Rule anyLiteral() { return FirstOf( nullLiteral(), booleanLiteral(), numberLiteral(), charLiteral(), stringLiteral()); } /** * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.7">JLS section 3.10.7</a> */ public Rule nullLiteral() { return Sequence( Sequence( String("null"), group.basics.testLexBreak()), set(actions.createNullLiteral(lastText())), group.basics.optWS()); } /** * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.5">JLS section 3.10.5</a> */ public Rule stringLiteral() { return Sequence( stringLiteralRaw(), set(actions.createStringLiteral(lastText())), group.basics.optWS()); } @SuppressSubnodes Rule stringLiteralRaw() { return Sequence( Ch('"'), ZeroOrMore(FirstOf( stringEscape(), Sequence(TestNot(CharSet("\"\r\n")), Any()))), Ch('"')); } Rule stringEscape() { return Sequence( Ch('\\'), FirstOf( Sequence(Optional(CharRange('0', '3')), Optional(CharRange('0', '7')), CharRange('0', '7')), Sequence(TestNot("\r\n"), Any()))); } /** * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.4">JLS section 3.10.4</a> */ public Rule charLiteral() { return Sequence( Sequence( Ch('\''), FirstOf( Sequence(escapedSequence(), Ch('\'')), Sequence( ZeroOrMore(Sequence(TestNot( FirstOf(Ch('\''), group.basics.lineTerminator())), Any())), Ch('\'')), Any())), set(actions.createCharLiteral(lastText())), group.basics.optWS()); } /** * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.6">JLS section 3.10.6</a> */ Rule escapedSequence() { return Sequence(Ch('\\'), FirstOf( Sequence(Optional(zeroToThree()), octalDigit(), Optional(octalDigit())), Any())); } Rule zeroToThree() { return FirstOf(Ch('0'), Ch('1'), Ch('2'), Ch('3')); } Rule octalDigit() { return FirstOf(Ch('0'), Ch('1'), Ch('2'), Ch('3'), Ch('4'), Ch('5'), Ch('6'), Ch('7')); } /** * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.3">JLS section 3.10.3</a> */ public Rule booleanLiteral() { return Sequence( Sequence( FirstOf(String("true"), String("false")), group.basics.testLexBreak()), set(actions.createBooleanLiteral(lastText())), group.basics.optWS()); } /** * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.1">JLS section 3.10.1</a> * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.2">JLS section 3.10.2</a> */ public Rule numberLiteral() { return Sequence( Test(Sequence(Optional(Ch('.')), CharRange('0', '9'))), FirstOf(hexLiteral(), fpLiteral()), set(lastValue()), group.basics.optWS()); } /** * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.1">JLS section 3.10.1</a> * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.2">JLS section 3.10.2</a> */ Rule fpLiteral() { return Sequence( Sequence( FirstOf( Sequence(OneOrMore(digit()), Optional(Sequence(Ch('.'), ZeroOrMore(digit())))), Sequence(Ch('.'), OneOrMore(digit()))), Optional( Sequence( CharIgnoreCase('e'), Optional(FirstOf(Ch('+'), Ch('-'))), OneOrMore(digit()))), numberTypeSuffix()), set(actions.createNumberLiteral(lastText()))); } /** * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.1">JLS section 3.10.1</a> * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.2">JLS section 3.10.2</a> */ Rule hexLiteral() { return Sequence( Sequence( Sequence(Ch('0'), CharIgnoreCase('x')), FirstOf( hexFP(), Sequence(OneOrMore(hexDigit()), numberTypeSuffix()) )), set(actions.createNumberLiteral(lastText()))); } /** * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.2">JLS section 3.10.2</a> */ Rule hexFP() { return Sequence( FirstOf( Sequence(Ch('.'), OneOrMore(hexDigit())), Sequence( OneOrMore(hexDigit()), Optional(Sequence(Ch('.'), ZeroOrMore(hexDigit()))))), Sequence( CharIgnoreCase('p'), Optional(FirstOf(Ch('+'), Ch('-'))), OneOrMore(digit())), numberTypeSuffix()); } Rule numberTypeSuffix() { return Optional(FirstOf(CharIgnoreCase('d'), CharIgnoreCase('f'), CharIgnoreCase('l'))); } Rule digit() { return FirstOf(Ch('0'), Ch('1'), Ch('2'), Ch('3'), Ch('4'), Ch('5'), Ch('6'), Ch('7'), Ch('8'), Ch('9'), Ch('0')); } Rule hexDigit() { return FirstOf(digit(), CharIgnoreCase('a'), CharIgnoreCase('b'), CharIgnoreCase('c'), CharIgnoreCase('d'), CharIgnoreCase('e'), CharIgnoreCase('f')); } }