Skip to content

Instantly share code, notes, and snippets.

@taku0
Created March 9, 2016 12:48
Show Gist options
  • Save taku0/3e7eb2f204d50b8ece48 to your computer and use it in GitHub Desktop.
Save taku0/3e7eb2f204d50b8ece48 to your computer and use it in GitHub Desktop.
tryGrammar(
"subtract",
MacroPEGParser.parse(
"""
|S = ReadRight("") !.;
|// the number of occurence of '1 represents a natural number.
|// a-b=c
|// Essentially, this checks a=b+c.
|ReadRight(Right)
| = &("1"* "-" Right "1") ReadRight(Right "1")
| / &("1"* "-" Right "=") ReadDiff(Right, "");
|
|ReadDiff(Right, Diff)
| = &("1"* "-" Right "=" Diff "1") ReadDiff(Right, Diff "1")
| / &("1"* "-" Right "=" Diff !.) Check(Right, Diff);
|
|Check(Right, Diff)
| = Right Diff "-" Right "=" Diff;
""".stripMargin),
"11-1=1", "1-1=", "111-11=1", // should match
"111-1=1", "111-1=111", "1-11=" // should not match
)
tryGrammar(
"exponent",
MacroPEGParser.parse(
"""
|S = ReadLeft("", "") !.;
|// the number of occurence of '1 represents a natural number.
|// |Seq| is the length of a sequence Seq.
|// ^ is exponent operator
|// ReadLeft("", "") checks input is a correct expression a^b=c.
|
|// Read a.
|// LeftAsOnes is a sequence of "1" where |LeftAsOnes| = |a|.
|// LeftAsDots is a sequence of . where |LeftAsDots| = |a|.
|ReadLeft(LeftAsOnes, LeftAsDots)
| = &(LeftAsOnes "1") ReadLeft(LeftAsOnes "1", LeftAsDots .)
| / &(LeftAsOnes "^") ComputePadding(LeftAsOnes, LeftAsDots, "");
|
|// Compute Padding which is a sequene of .
|// where |Padding| + |LeftAsDots| = |Input|
|ComputePadding(LeftAsOnes, LeftAsDots, Padding)
| = &(Padding LeftAsDots .) ComputePadding(LeftAsOnes, LeftAsDots, Padding .)
| / &(Padding LeftAsDots !.) ReadRight(LeftAsOnes, Padding, "", "1");
|
|// Read b.
|// Exp = a^Right.
|ReadRight(Left, Padding, Right, Exp)
| = &(Left "^" Right "1") Multiply(Left, Padding, Right "1", Exp, "", "")
| / &(Left "^" Right "=") Check(Left, Right, Exp);
|
|// Compute Left * OldExp.
|// This adds OldExp Left times into Exp.
|// I is a loop counter.
|Multiply(Left, Padding, Right, OldExp, Exp, I)
| = &(Padding I .) Multiply(Left, Padding, Right, OldExp, Exp OldExp, I .)
| / &(Padding I !.) ReadRight(Left, Padding, Right, Exp);
|
|// Check whole input.
|Check(Left, Right, Exp)
| = Left "^" Right "=" Exp;
""".stripMargin),
"11^111=11111111", "11^=1", "1^11=1", "^11=", // should match
"11^111=1111111", "11^111=111111111" // should not match
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment