Last active
November 9, 2015 01:01
-
-
Save ppopoff/1bbf022327750f37ebcc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.parboiled2._ | |
/** | |
* Constants and char predicates | |
*/ | |
object BkvRecognizer { | |
val WhitespaceChars = "\n\t " | |
val IdentifierChar = CharPredicate.AlphaNum ++ '.' ++ '_' | |
/** | |
* Identifier must start only with a letter or underscore, | |
* and contain latin letters, digits, underscore and dots | |
*/ | |
val IdentifierFirstChar = CharPredicate.Alpha ++ '_' | |
val IdentifierChar = CharPredicate.AlphaNum ++ '.' ++ '_' | |
val BlockBeginning = '{' | |
val BlockEnding = '}' | |
} | |
/** | |
* A recognizer for BKV's grammar | |
* | |
* Recognizer != Parser. It doesn't extract any data. | |
* It just matches the input | |
*/ | |
class BkvRecognizer(val input: ParserInput) extends Parser with QuotedStringSupport { | |
import BkvRecognizer._ | |
def WhiteSpace = rule { | |
anyOf(WhitespaceChars) | |
} | |
def OptWs = rule { | |
zeroOrMore(WhiteSpace) | |
} | |
def Newline = rule { | |
'\r'.? ~ '\n' | |
} | |
def Identifier = rule { | |
IdentifierFirstChar ~ zeroOrMore(IdentifierChar) | |
} | |
def Key = rule { | |
Identifier | |
} | |
def Value = rule { | |
QuotedString | |
} | |
def KeyValuePair = rule { | |
Key ~ OptWs ~ "=" ~ OptWs ~ Value | |
} | |
def Block = rule { | |
BlockName ~ OptWs ~ BlockBeginning ~ Nodes ~ BlockEnding | |
} | |
def BlockName = rule { | |
Identifier | |
} | |
// Recursive call. Type MUST be specified | |
def Node: Rule0 = rule { | |
KeyValuePair | Block | |
} | |
def Nodes = rule { | |
OptWs ~ zeroOrMore(Node).separatedBy(Newline ~ OptWs) ~ OptWs | |
} | |
def Root = rule { | |
Nodes ~ EOI | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.parboiled2._ | |
object QuotedStringSupport { | |
/** | |
* Look here for the example. | |
* https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences | |
*/ | |
val CharsToBeEscaped = "abfnrtv\\\"" | |
val BackSlash = '\\' | |
/** | |
* All printable characters except double quotation and backslash | |
*/ | |
val AllowedChars = CharPredicate.Printable -- BackSlash -- '"' | |
} | |
/** | |
* Support for strings with double quotations | |
* and c-like escaping rules | |
*/ | |
trait QuotedStringSupport { this: Parser => | |
import QuotedStringSupport._ | |
def QuotedString: Rule0 = rule { | |
'"' ~ QuotedStringContent ~ '"' | |
} | |
def QuotedStringContent: Rule0 = rule { | |
zeroOrMore(AllowedChars | DoubleQuotedStringEscapeSequence) | |
} | |
def DoubleQuotedStringEscapeSequence = rule { | |
'\\' ~ anyOf(CharsToBeEscaped) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment