fix string escape handling

This commit is contained in:
sbyrne
2021-06-04 23:10:33 -04:00
parent 906345753e
commit 2da9eadbac
2 changed files with 44 additions and 19 deletions

View File

@@ -11,6 +11,7 @@ import org.parboiled.matchers.Matcher
import org.parboiled.matchers.TestMatcher import org.parboiled.matchers.TestMatcher
import org.parboiled.parserunners.TracingParseRunner import org.parboiled.parserunners.TracingParseRunner
import org.parboiled.support.ParseTreeUtils import org.parboiled.support.ParseTreeUtils
import org.parboiled.support.StringVar
object FigParser { object FigParser {
@@ -359,43 +360,57 @@ open class FigPegParser: BaseParser<Any>() {
// pushes FigString // pushes FigString
open fun StringLiteralRule( terminators:String? ): Rule { open fun StringLiteralRule( terminators:String? ): Rule {
return FirstOf( return FirstOf(
Sequence( QuotedStringRule(),
"\"", UnquotedStringRule(terminators)
TextOrEmptyRule(charsRequiringEscape = "\""),
push( FigString( match() ) ),
"\""
),
Sequence(
TextRule(charsRequiringEscape = "${WHITESPACE}${terminators?:""}"),
push( FigString( match() ) ),
TestWhitespaceTerminatorOrEnd(terminators)
)
).suppressSubnodes() ).suppressSubnodes()
} }
// pushes FigString
open fun QuotedStringRule(): Rule {
val text = StringVar()
return Sequence(
"\"",
TextOrEmptyRule(charsRequiringEscape = "\"",var_=text),
push( FigString( text.get() ) ),
"\""
)
}
// pushes FigString
open fun UnquotedStringRule(terminators:String?): Rule {
val text = StringVar()
return Sequence(
TextRule(charsRequiringEscape = "${WHITESPACE}${terminators?:""}",var_=text),
push( FigString( text.get() ) ),
TestWhitespaceTerminatorOrEnd(terminators)
)
}
/** /**
* A text string where the specified characters and backslash must be escaped with a backslash. * A text string where the specified characters and backslash must be escaped with a backslash.
* The text can be empty. * The text can be empty.
* *
* @param charsRequiringEscape * @param charsRequiringEscape
*/ */
open fun TextOrEmptyRule(charsRequiringEscape: String): Rule { open fun TextOrEmptyRule(charsRequiringEscape: String,var_:StringVar): Rule {
return ZeroOrMore( return ZeroOrMore(
FirstOf( FirstOf(
Sequence( Sequence(
'\\', '\\',
AnyOf(charsRequiringEscape + '\\') AnyOf(charsRequiringEscape + '\\'),
var_.append(match())
), ),
OneOrMore( OneOrMore(
Sequence( Sequence(
TestNot( TestNot(
AnyOf(charsRequiringEscape + '\\') AnyOf(charsRequiringEscape + '\\')
), ),
ANY ANY,
var_.append(match())
) )
).suppressSubnodes() ).suppressSubnodes()
) )
) )
} }
/** /**
@@ -404,17 +419,19 @@ open class FigPegParser: BaseParser<Any>() {
* *
* @param charsRequiringEscape * @param charsRequiringEscape
*/ */
open fun TextRule(charsRequiringEscape: String): Rule { open fun TextRule(charsRequiringEscape: String,var_:StringVar): Rule {
return OneOrMore( return OneOrMore(
FirstOf( FirstOf(
Sequence( Sequence(
'\\', '\\',
AnyOf(charsRequiringEscape + '\\') AnyOf(charsRequiringEscape + '\\'),
var_.append(match())
), ),
OneOrMore( OneOrMore(
Sequence( Sequence(
TestNot(AnyOf(charsRequiringEscape + '\\')), TestNot(AnyOf(charsRequiringEscape + '\\')),
ANY ANY,
var_.append(match())
) )
).suppressSubnodes() ).suppressSubnodes()
) )

View File

@@ -67,6 +67,14 @@ class FigParserTest {
)) ))
) )
@Test
fun testString() = test(
"abc",
FigList(mutableListOf(
FigString("abc")
))
)
@Test @Test
fun testNumber() = test( fun testNumber() = test(
"1", "1",
@@ -94,7 +102,7 @@ class FigParserTest {
@Test @Test
fun escapeQuotedString() = test( fun escapeQuotedString() = test(
""""a\ b""", "\"a b\"",
FigList(mutableListOf( FigList(mutableListOf(
FigString("a b") FigString("a b")
)) ))