3

I have the following PEGjs productions:

NameStartChar = ":" / [A-Z] / "_" / [a-z] / [\u00C0-\u00D6] / [\u00D8-\u00F6] / [\u00F8-\u02FF] / [\u0370-\u037D] /
                [\u037F-\u1FFF] / [\u200C-\u200D] / [\u2070-\u218F] / [\u2C00-\u2FEF] / [\u3001-\uD7FF] /
                [\uF900-\uFDCF] / [\uFDF0-\uFFFD] / [\uD800-\uDB7F][\uDC00-\uDFFF]

NameChar = NameStartChar / "-" / "." / [0-9] / "\u00B7" / [\u0300-\u036F] / [\u203F-\u2040]

Name = NameStartChar NameChar*

I'd like to somehow get true if my input string matches Name, and false otherwise. I also don't care about parsing out the component parts.

However, PEGjs really wants to throw an exception if the match fails.

I could of course wrap it in a try/catch, but I'd prefer to avoid that. And I'd like to avoid collecting the parsed components as well (i.e., I don't need ["a", ["b", "c", "d"]] when matching "abcd", I just need true).

Is there some hidden PEGjs feature that will make this work? Maybe a clever action, or an innovative use of combinators?

Or perhaps I should be using an entirely different tool, and not a parser-generator? If so, does anyone know what I should be using?

Domenic
  • 110,262
  • 41
  • 219
  • 271

3 Answers3

4

We can use Name { return true } / { return false } to get an expression that will return true if the rule matched. Then, we can add !. to check that we are at the end of the input for the true case, and .* to skip to the end in the false case. So we get:

ValidateName = Name !. { return true } / .* { return false }
0

The language of Names you define seems regular to me, so you could do it with a regular expression. Depending on the language you use you would call a function match or find to test your input.

Remember to put begin and end of line anchors so it matches the entire input, for example

^(:|[A-Z]|_|etc)(:|[A-Z]|_|etc|-|\.|[0-9]|etc)*$
1010
  • 1,779
  • 17
  • 27
  • Yes, it definitely is, but I want to reuse the existing BNFs in specs instead of having to translate them to regular expression syntax. – Domenic Dec 29 '14 at 00:00
  • @Domenic maybe this works (disclaimer because I have almost no experience with PEGs): add a rule TestName = Name / .* with appropiate semantic actions on either side of /. The right side should match anything only if it wasn't a Name. – 1010 Dec 29 '14 at 01:56
-1
ValidateName = Name { return true } / { return false }

If you want to validate input without advancing the parser position with a sub-expression you can use &Name.