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 -~----------~----~----~----~------~----~------~--~---