Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

firstOf() ignores overridden fromStringLiteral(String) #31

Open
akirschbaum opened this issue May 30, 2015 · 1 comment
Open

firstOf() ignores overridden fromStringLiteral(String) #31

akirschbaum opened this issue May 30, 2015 · 1 comment

Comments

@akirschbaum
Copy link

The following grammar contains three rules. Each of these rules should match inputs "a" or "b", optionally followed by spaces.

rule1 explicitly matches the trailing whitespace with zeroOrMore(sp()). This rule matches the input "a".

rule2 implicitly matches the trailing whitespace by overriding fromStringLiteral(String) and adding zeroOrMore(sp()). That is: "x" matches this string; "x " matches sequence("x", zeroOrMore(sp())). This rule does NOT match the input "a". This is incorrect.

rule3 is the same as rule2 but also matches cr(). This slight change causes the rule to match the input "a".

Note: it seems that the actual change in rule3 is not important: If at least one non-String argument is present, the rule does match the input "a".

The issue seems to be that if all arguments of firstOf() are string literals, the overloaded fromStringLiteral(String) is ignored.

$ gradle
:compileJava
:processResources UP-TO-DATE
:classes
:run
rule1: true
rule2: false
rule3: true

BUILD SUCCESSFUL

Total time: 5.954 secs
$ cat build.gradle
defaultTasks 'run'

apply plugin: 'application'
apply plugin: 'java'

sourceCompatibility = 1.8
mainClassName = 'app.Main'

dependencies {
    compile 'com.github.fge:grappa:2.0.0'
}

repositories {
    mavenCentral()
}
$ cat src/main/java/app/Main.java
package app;

import com.github.fge.grappa.Grappa;
import com.github.fge.grappa.buffers.CharSequenceInputBuffer;
import com.github.fge.grappa.parsers.BaseParser;
import com.github.fge.grappa.rules.Rule;
import com.github.fge.grappa.run.ListeningParseRunner;

public class Main {

    public static void main(final String[] args) {
        final Parser1 parser = Grappa.createParser(Parser1.class);
        final CharSequenceInputBuffer buffer = new CharSequenceInputBuffer("a");
        System.out.println("rule1: "+new ListeningParseRunner<>(parser.rule1()).run(buffer).isSuccess());
        System.out.println("rule2: "+new ListeningParseRunner<>(parser.rule2()).run(buffer).isSuccess());
        System.out.println("rule3: "+new ListeningParseRunner<>(parser.rule3()).run(buffer).isSuccess());
    }

    public static class Parser1 extends BaseParser<Object> {

        public Rule rule1() {
            return firstOf(sequence(fromStringLiteral("a"), zeroOrMore(sp())), sequence(fromStringLiteral("b"), zeroOrMore(sp())));
        }

        public Rule rule2() {
            return firstOf("a ", "b ");
        }

        public Rule rule3() {
            return firstOf("a ", "b ", cr());
        }

        @Override
        protected Rule fromStringLiteral(final String string) {
            return string.endsWith(" ") ? sequence(super.fromStringLiteral(string.substring(0, string.length()-1)), zeroOrMore(sp())) : super.fromStringLiteral(string);
        }

    }

}
@akirschbaum
Copy link
Author

A better example for rule3 would be: firstOf("a ", "b ", NOTHING).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant