From: Mark Probert Date: 2002-10-11T11:12:13+09:00 Subject: [ANN] Coco/Rb LL(1) Recursive-decent scanner/parser Hi, I'd like to announce to the Ruby Community that I have posted Coco/Rb onto RAA. This is the initial release of the software and there is still a lot of testing to do. I am very interested in feedback and/or suggestions. The distribution currently works on Ruby 1.7.2 (Win32) and 1.7.3 (Solaris - gcc), so I will be eager to know if it works under linux (I am assuming that it will). Included in the kit are a number of toy grammars: + Expr -- from the Dragon Book + Calc -- Expr with variables + Clang -- a Pascal/C combo + Cdecl -- a toy to convert C declarations to words (ptr to ptr to ...) I haven't started on an LL(1) definition for Ruby yet ;-) Thanks in advance, -mark. *** What is Coco/Rb? Coco/Rb generates recursive descent parsers, their associated scanners, from LL(1) attributed grammars. Coco/Rb also generates a driver for producing Ruby extensions (along with associated extconf.rb and depends files). *** What is a recursive decent parser? To quote from Pat Terry's web page: Coco/R combines the functionality of the well-known UNIX tools lex and yacc, to form an extremely easy to use compiler generator that generates recursive descent parsers, their associated scanners, and (in some versions) a driver program, from attributed grammars (written using EBNF syntax with attributes and semantic actions) which conform to the restrictions imposed by LL(1) parsing (rather than LALR parsing, as allowed by yacc). This means that you have one file (usually ending in .atg) that specifies how to scan and parse a source file or array of strings. One section of the file decribes how to scan the token, and another how to parse them. An simple example grammar is the following (from the Dragon book): COMPILER Expr /* This is a simple expression calculator */ CHARACTERS letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz". digit = "0123456789". TOKENS ident = letter {letter|digit}. number = digit { digit }. COMMENTS FROM "--" TO eol /*--------------------Parser Specification -------------------*/ PRODUCTIONS Expr = StatSeq . StatSeq = SYNC { Stat ";" SYNC} . Stat = (. int value; char str[255]; .) Expression<&value> (. sprintf(str, "%d\n", value); t_capture_output(str) .) . Expression = (. int result1, result2; .) Term<&result1> { "+" Term<&result2> (. result1 += result2; .) | "-" Term<&result2> (. result1 -= result2; .) } (. *result = result1; .) . Term = (. int result1, result2; .) Factor<&result1> { '*' Factor<&result2> (. result1 *= result2; .) | '/' Factor<&result2> (. result1 /= result2; .) } (. *result = result1; .) . Factor = (. int sign = 1; .) [ "-" (. sign =- 1; .) ] ( Number | "(" Expression ")" ) (. *result *= sign; .) . Number = (. char buff[20]; .) number (. LEX_S(buff); *result = atoi(buff); .) . END Expr.