This project has moved. For the latest updates, please go here.

How to distinguish real_number+"KeyA" from int_number+"KeyB"

May 14, 2010 at 4:40 PM


My grammar can have 2 statements: real_number + "SEC" or int_number + "CLK".

real_number forms are 1, 1E0, 1E+0, 1E-0, 1.0, 1.0E0, 1.0E+0, and 1.0E-0.
Grammar handles statements "1.0 sec" and "1 clk".

But "1 sec" (should be valid) causes a syntax error (expected: clk).

How to solve this problem?

    public class TryGrammar : Grammar
        public TryGrammar() : base(false)
            var real_number = new NumberLiteral("real_number");
            var int_number = new NumberLiteral("int_number", NumberOptions.IntOnly);

            var sec_stmt = new NonTerminal("sec_stmt");
            var clk_stmt = new NonTerminal("clk_stmt");
            var stmt = new NonTerminal("expr");

            sec_stmt.Rule = real_number + "SEC";
            clk_stmt.Rule = int_number + "CLK";
            stmt.Rule = sec_stmt | clk_stmt;

            // ok: 1.0 sec
            // ok: 1 clk
            // error: 1 sec

            this.Root = stmt;

May 18, 2010 at 6:13 PM
The reason it fails is because your scanner settings are ambiguous. Scanner cannot decide for sure between real number and integer in case of "1", so it chooses int_number, and then parser fails. This ambiguity cannot be clearly detected automatically, so it's not reported after grammar analysis. You have to reformulate your grammar, using one number literal (real_number), and then validate during or after parsing that for "CLK" expression the number is int.
May 27, 2010 at 10:16 AM

Thanks for reply.

 sec_stmt.Rule = (int_number | real_number) + "SEC"; // worked in my case