On Dec 30, 2015, at 6:35 AM, Ludovic Courtès wrote: >> Demo: >> Use C parser and pretty printer to clean up C expressions (e.g., remove unneeded paren’s): > > The demo is already quite impressive! Thanks. > What subset of C99 and GNU99 is currently supported? I can’t remember if any C99 items are not in. I do not have any GNU99 extensions in there. However, this is not a faithful parser for C99. The purpose is not to compile, but to generate translators and auto-coders. I have built the parser with the following features: 1) The c-preprocessor parsing is merged in with the lexical analyzer. 2) The parse tree is “file oriented”, so that you can track what elements are in the top-level file. 3) The parser will parse comments. so #ifdef ABC #include “xyz.h” #endif foo_t x; /* this is a decl */ comes out (trans-unit (cpp-stmt (if (defined "ABC"))) (cpp-stmt (include "\"xyz.h\"" (trans-unit (decl (decl-spec-list (stor-spec (typedef)) (type-spec (fixed-type "int"))) (init-declr-list (init-declr (ident "foo_t"))))))) (cpp-stmt (endif)) (decl (decl-spec-list (type-spec (typename "foo_t"))) (init-declr-list (init-declr (ident "x"))) (comment " this is a decl "))) and the pretty-printer generates #if defined(ABC) #include "xyz.h" #endif foo_t x; /* this is a decl */ > What are you aiming for with the tree-il conversion? That sounds > interesting. :-) The purpose of the tree-il conversion is to support “,L ” at the guile prompt. And the tree-il code is done for javascript and a simple calculator, not C. I just tried the javascript and it is not working, but here is a small demo with the simple calculator. The calc files (parser, compiler and spec) are included below. scheme@(guile-user)> ,L calc Happy hacking with calc! To switch back, type `,L scheme'. calc@(guile-user)> a = 3 + 4 calc@(guile-user)> ,L scheme Happy hacking with Scheme! To switch back, type `,L calc'. scheme@(guile-user)> a $1 = 7 PARSER: (define-module (nyacc lang calc parser) #:export (calc-parse calc-spec calc-mach) #:use-module (nyacc lalr) #:use-module (nyacc lex) #:use-module (nyacc parse) ) (define calc-spec (lalr-spec (prec< (left "+" "-") (left "*" "/")) (start stmt-list-proxy) (grammar (stmt-list-proxy (stmt-list "\n" ($$ `(stmt-list ,@(reverse $1))))) (stmt-list (stmt ($$ (list $1))) (stmt-list ";" stmt ($$ (cons $3 $1)))) (stmt (ident "=" expr ($$ `(assn-stmt ,$1 ,$3))) (expr ($$ `(expr-stmt ,$1))) ( ($$ '(empty-stmt)))) (expr (expr "+" expr ($$ `(add ,$1 ,$3))) (expr "-" expr ($$ `(sub ,$1 ,$3))) (expr "*" expr ($$ `(mul ,$1 ,$3))) (expr "/" expr ($$ `(div ,$1 ,$3))) ('$fixed ($$ `(fixed ,$1))) ('$float ($$ `(float ,$1))) ("(" expr ")" ($$ $2))) (ident ('$ident ($$ `(ident ,$1)))) ))) (define calc-mach (compact-machine (hashify-machine (make-lalr-machine calc-spec)))) (define calc-parse (let ((gen-lexer (make-lexer-generator (assq-ref calc-mach 'mtab) #:space-chars " \t")) (parser (make-lalr-ia-parser calc-mach))) (lambda* (#:key (debug #f)) (parser (gen-lexer) #:debug debug)))) COMPILER: (define-module (nyacc lang calc compiler) #:export (calc-sxml->tree-il) #:use-module (sxml match) #:use-module (sxml fold) #:use-module (language tree-il)) (define (fup tree) (sxml-match tree ((fixed ,fx) `(const ,(string->number fx))) ((float ,fl) `(const ,(string->number fl))) ((ident ,id) `(toplevel ,(string->symbol id))) ((add ,lt ,rt) `(apply (toplevel +) ,lt ,rt)) ((sub ,lt ,rt) `(apply (toplevel -) ,lt ,rt)) ((mul ,lt ,rt) `(apply (toplevel *) ,lt ,rt)) ((div ,lt ,rt) `(apply (toplevel /) ,lt ,rt)) ((assn-stmt (toplevel ,lhs) ,rhs) `(define ,lhs ,rhs)) ((empty-stmt) '(begin)) ((stmt-list ,items ...) `(begin ,items ...)) (,otherwise tree))) (define (calc-sxml->tree-il exp env opts) (let* ((tree (foldt fup identity exp)) (code (parse-tree-il tree))) (values code env env))) SPEC: (define-module (language calc spec) #:export (calc) #:use-module (system base language) #:use-module (nyacc lang calc parser) #:use-module (nyacc lang calc compiler)) (define (calc-reader port env) (let ((iport (current-input-port))) (dynamic-wind (lambda () (set-current-input-port port)) (lambda () (calc-parse #:debug #f)) (lambda () (set-current-input-port iport))))) (define-language calc #:title "calc" #:reader calc-reader #:compilers `((tree-il . ,calc-sxml->tree-il)) #:printer write)