Hi,

On Nov 28, 11:30 am, Rémi Forax <[EMAIL PROTECTED]> wrote:
> We throw this approach 3 months later because
>   - it's not really readable thus difficult to debug :)
I beg to differ.  I find it much easier to read, write and debug.

>   - the Java type of each non-terminal must be the same and with this format
>     that type is repeated on each method that defines a rule containing
>     the non-terminal.
I just don't see why it has to.  I wrote the yacc parser using Java
annotation approach and it involves a number of different data types

http://code.google.com/p/cookcc/source/browse/trunk/src/org/yuanheng/cookcc/input/yacc/YaccParser.java

>   - there is a third point but i'm not able to recall it now :(>
> So we decide to write grammars as we used to :)
> And to link the grammar to the semantics, we add a name at the end of
> each production
> (between curly braces) and a way to declare the type of each terminal
> and non-terminal at one place.
>
> Here is an example of a calc 
> :http://gforgeigm.univ-mlv.fr/scm/viewvc.php/trunk/samples/calc-ast/ca...
>
> and it's generate an interface that you can implement to provide the
> semantics.http://gforgeigm.univ-mlv.fr/scm/viewvc.php/trunk/samples/calc-ast/sr...

On the contrary, I think your code precisely listed the shortcomings
CookCC is trying to address

1. Separate lexer and parser, so users have to hook them up by
themselves.

2. Function names are specified in the grammar file has to be exactly
matched against function names in Java files.  This creates a name
matching issue.  The problem can only be discovered after compiling
the grammar file (to generate java code), and then compiling the java
source files together.

3. Several different files.  This creates a file management issue.  At
least I couldn't tell without looking at build.xml that which files
are required for the specific lexer / parser.  This is a particularly
an issue in cases where multiple small grammar parsers are used in a
project, since java files are batch compiled.

In contrast, with CookCC java annotation input, lexer and parser
function names can be arbitrary without worrying about spelling
mistakes.  Lexer and parser are automatically hooked up.  There is
only a single input file to deal with (and you can have color syntax
highlighting without any extra efforts).

Here is equivalent Java code in CookCC that parse your example.

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;

import org.yuanheng.cookcc.*;

@CookCCOption
public class Calculator extends Parser
{
        @CookCCToken
        static enum Token
        {
                VALUE,
                @TokenGroup (type = TokenType.LEFT)
                EQUALS,
                @TokenGroup (type = TokenType.LEFT)
                PLUS, MINUS,
                @TokenGroup (type = TokenType.LEFT)
                STAR
        }

        /////////////////// Lexer /////////////////////////

        @Lexs (patterns = {
                @Lex (pattern = "'+'", token = "PLUS"),
                @Lex (pattern = "'-'", token = "MINUS"),
                @Lex (pattern = "'*'", token = "STAR"),
                @Lex (pattern = "'='", token = "EQUALS"),
                @Lex (pattern = "[+\\-*=();]")
        })
        int scanSymbols ()
        {
                return yyText ().charAt (0);
        }

        @Lex (pattern = "[0-9]+", token = "VALUE")
        Integer scanInt ()
        {
                return Integer.parseInt (yyText ());
        }

        @Lex (pattern = "[ \\t\\r\\n]+")
        void scanSpace ()
        {
        }

        @Lex (pattern = "#([^\\r\\n])*(\\r)?\\n")
        void scanComment ()
        {
                System.out.println ("found comment " + yyText ());
        }

        @Lex (pattern = "<<EOF>>", token = "$")
        void scanEof ()
        {
        }

        @Lex (pattern = ".")
        void invalidChar ()
        {
                System.out.println ("invalid character: " + yyText ());
        }

        /////////////////// Parser /////////////////////////

        @Rules (rules = {
                @Rule (lhs = "start", rhs = "start line"),
                @Rule (lhs = "start", rhs = "")
        })
        void parseStart ()
        {
        }

        @Rules (rules = {
                @Rule (lhs = "line", rhs = "expr ';'", args = "1"),
                @Rule (lhs = "line", rhs = "expr", args = "1")
        })
        void parseLine (Integer expr)
        {
                System.out.println ("value =" + expr);
        }

        @Rule (lhs = "line", rhs = "error ';'")
        void parseLineError ()
        {
        }

        @Rules (rules = {
                @Rule (lhs = "expr", rhs = "VALUE", args = "1"),
                @Rule (lhs = "expr", rhs = "'(' expr ')'", args = "2")
        })
        Integer parseExpr (Integer value)
        {
                return value;
        }

        @Rule (lhs = "expr", rhs = "expr PLUS expr", args = "1 3")
        Integer parsePlusExpr (Integer expr1, Integer expr2)
        {
                return expr1 + expr2;
        }

        @Rule (lhs = "expr", rhs = "expr MINUS expr", args = "1 3")
        Integer parseMinusExpr (Integer expr1, Integer expr2)
        {
                return expr1 - expr2;
        }

        @Rule (lhs = "expr", rhs = "expr STAR expr", args = "1 3")
        Integer parseStarExpr (Integer expr1, Integer expr2)
        {
                return expr1 - expr2;
        }

        @Rule (lhs = "expr", rhs = "expr EQUALS expr", args = "1 3")
        Integer parseEqualsExpr (Integer expr1, Integer expr2)
        {
                return expr1.intValue () == expr2.intValue () ? 1 : 0;
        }

        @Rule (lhs = "expr", rhs = "'(' error ')'")
        Integer parseErrorExpr ()
        {
                return 0;
        }

        public static void main (String[] args) throws IOException
        {
                InputStream is;
                if (args.length > 0)
                        is = new FileInputStream (args[0]);
                else
                        is = System.in;
                Calculator calc = new Calculator ();
                calc.setInput (is);
                if (calc.yyParse () == 0)
                        System.out.println ("source recognized");
        }
}


>
> Using annotations instead of a DSL is not in my opinion a good idea,
> at least until annotations are String based.> Patrick
>
> Rémi

Sorry for being contentious :)

Heng Yuan

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "JVM 
Languages" group.
To post to this group, send email to jvm-languages@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/jvm-languages?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to