mach.scm 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892
  1. ;;; lang/c99/mach.scm - C parser grammer
  2. ;; Copyright (C) 2015-2018 Matthew R. Wette
  3. ;;
  4. ;; This library is free software; you can redistribute it and/or
  5. ;; modify it under the terms of the GNU Lesser General Public
  6. ;; License as published by the Free Software Foundation; either
  7. ;; version 3 of the License, or (at your option) any later version.
  8. ;;
  9. ;; This library is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. ;; Lesser General Public License for more details.
  13. ;;
  14. ;; You should have received a copy of the GNU Lesser General Public License
  15. ;; along with this library; if not, see <http://www.gnu.org/licenses/>.
  16. ;;; Notes:
  17. ;; This is a C parser, based on ISO-C99, with comments and CPP statements.
  18. ;; Currentl K&R function definitions are not supported:
  19. ;; int f(x) int x; { ... } => syntax error
  20. ;; because they lead to an ambiguous grammar, I believe:
  21. ;; int f(x) __attribute__((__static__)) int x; { ... }
  22. ;; See also:
  23. ;; http://www.quut.com/c/ANSI-C-grammar-y.html - C11 grammar
  24. ;; https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions
  25. ;;; Code:
  26. (define-module (nyacc lang c99 mach)
  27. #:export (c99-spec c99-mach c99x-spec c99x-mach gen-c99-files)
  28. #:use-module (nyacc lang c99 cpp)
  29. #:use-module (nyacc lang util)
  30. #:use-module (nyacc lalr)
  31. #:use-module (nyacc parse)
  32. #:use-module (nyacc lex)
  33. #:use-module (nyacc util)
  34. #:use-module ((srfi srfi-43) #:select (vector-map)))
  35. ;; @deffn {Variable} c99-spec
  36. ;; This variable is the specification a-list for the hacked ISO C99 language.
  37. ;; Well, actually, this does not produce pure C99 spec: it has been extended
  38. ;; to be able be used for practical purposes so it now parses forms like
  39. ;; @code{__asm__} and @code{__attribute__}.
  40. ;; Run this through @code{make-lalr-machine} to get an a-list for the
  41. ;; automaton. The grammar is modified to parse CPP statements and comments.
  42. ;; The output of the end parser will be a SXML tree (w/o the @code{*TOP*} node.
  43. ;; @end deffn
  44. (define c99-spec
  45. (lalr-spec
  46. (notice (string-append "Copyright (C) 2016-2018 Matthew R. Wette"
  47. license-lgpl3+))
  48. (prec< 'then "else") ; "then/else" SR-conflict resolution
  49. (prec< 'imp ; "implied type" SR-conflict resolution
  50. (nonassoc "char" "short" "int" "long" "_Fract" "_Accum" "_Sat")
  51. (nonassoc "float" "double" "_Complex"))
  52. (prec< 'shift-on-attr ; living on the edge ...
  53. (nonassoc "__attribute__" "__packed__" "__aligned__" "__alignof__")
  54. 'reduce-on-attr
  55. 'reduce-on-semi
  56. (nonassoc "*" "(" '$ident))
  57. (start translation-unit)
  58. (grammar
  59. ;; === expressions ========================================================
  60. (primary-expression ; S 6.5.1
  61. (identifier ($$ `(p-expr ,$1)))
  62. (constant ($$ `(p-expr ,$1)))
  63. (string-literal ($$ `(p-expr ,$1)))
  64. ("(" expression ")" ($$ $2))
  65. ("(" "{" ($$ (cpi-push)) block-item-list ($$ (cpi-pop)) "}" ")"
  66. ($$ `(stmt-expr (@ (extension "GNUC")) ,$4))))
  67. (postfix-expression ; S 6.5.2
  68. (primary-expression)
  69. (postfix-expression "[" expression "]" ($$ `(array-ref ,$3 ,$1)))
  70. (postfix-expression "(" argument-expression-list ")"
  71. ($$ `(fctn-call ,$1 ,(tl->list $3))))
  72. (postfix-expression "(" ")" ($$ `(fctn-call ,$1 (expr-list))))
  73. (postfix-expression "." identifier ($$ `(d-sel ,$3 ,$1)))
  74. (postfix-expression "->" identifier ($$ `(i-sel ,$3 ,$1)))
  75. (postfix-expression "++" ($$ `(post-inc ,$1)))
  76. (postfix-expression "--" ($$ `(post-dec ,$1)))
  77. ("(" type-name ")" "{" initializer-list "}"
  78. ($$ `(comp-lit ,$2 ,(tl->list $5))))
  79. ("(" type-name ")" "{" initializer-list "," "}"
  80. ($$ `(comp-lit ,$2 ,(tl->list $5)))))
  81. (argument-expression-list
  82. (assignment-expression ($$ (make-tl 'expr-list $1)))
  83. (argument-expression-list "," assignment-expression ($$ (tl-append $1 $3)))
  84. ;; The following is a hack to deal with using abstract declarations
  85. ;; as arguments to CPP macros (e.g., see offsetof in <stddef.h>).
  86. (arg-expr-hack ($$ (make-tl 'expr-list $1)))
  87. (argument-expression-list "," arg-expr-hack ($$ (tl-append $1 $3))))
  88. (arg-expr-hack
  89. (declaration-specifiers
  90. abstract-declarator ($$ `(param-decl ,(tl->list $1) $2)))
  91. (declaration-specifiers ($$ `(param-decl ,(tl->list $1)))))
  92. (unary-expression
  93. (postfix-expression) ; S 6.5.3
  94. ("++" unary-expression ($$ `(pre-inc ,$2)))
  95. ("--" unary-expression ($$ `(pre-dec ,$2)))
  96. (unary-operator cast-expression ($$ (list $1 $2)))
  97. ("sizeof" unary-expression ($$ `(sizeof-expr ,$2)))
  98. ("sizeof" "(" type-name ")" ($$ `(sizeof-type ,$3)))
  99. )
  100. (unary-operator ("&" ($$ 'ref-to)) ("*" ($$ 'de-ref))
  101. ("+" ($$ 'pos)) ("-" ($$ 'neg))
  102. ("~" ($$ 'bitwise-not)) ("!" ($$ 'not)))
  103. (cast-expression ; S 6.5.4
  104. (unary-expression)
  105. ("(" type-name ")" cast-expression ($$ `(cast ,$2 ,$4))))
  106. (multiplicative-expression ; S 6.5.5
  107. (cast-expression)
  108. (multiplicative-expression "*" cast-expression ($$ `(mul ,$1 ,$3)))
  109. (multiplicative-expression "/" cast-expression ($$ `(div ,$1 ,$3)))
  110. (multiplicative-expression "%" cast-expression ($$ `(mod ,$1 ,$3))))
  111. (additive-expression ; S 6.5.6
  112. (multiplicative-expression)
  113. (additive-expression "+" multiplicative-expression ($$ `(add ,$1 ,$3)))
  114. (additive-expression "-" multiplicative-expression ($$ `(sub ,$1 ,$3))))
  115. (shift-expression ; S 6.5.7
  116. (additive-expression)
  117. (shift-expression "<<" additive-expression ($$ `(lshift ,$1 ,$3)))
  118. (shift-expression ">>" additive-expression ($$ `(rshift ,$1 ,$3))))
  119. (relational-expression ; S 6.5.8
  120. (shift-expression)
  121. (relational-expression "<" shift-expression ($$ `(lt ,$1 ,$3)))
  122. (relational-expression ">" shift-expression ($$ `(gt ,$1 ,$3)))
  123. (relational-expression "<=" shift-expression ($$ `(le ,$1 ,$3)))
  124. (relational-expression ">=" shift-expression ($$ `(ge ,$1 ,$3))))
  125. (equality-expression ; S 6.5.9
  126. (relational-expression)
  127. (equality-expression "==" relational-expression ($$ `(eq ,$1 ,$3)))
  128. (equality-expression "!=" relational-expression ($$ `(ne ,$1 ,$3))))
  129. ;; called AND-expression
  130. (bitwise-and-expression ; S 6.5.10
  131. (equality-expression)
  132. (bitwise-and-expression "&" equality-expression
  133. ($$ `(bitwise-and ,$1 ,$3))))
  134. ;; called exclusive-OR-expression
  135. (bitwise-xor-expression ; S 6.5.11
  136. (bitwise-and-expression)
  137. (bitwise-xor-expression "^" bitwise-and-expression
  138. ($$ `(bitwise-xor ,$1 ,$3))))
  139. ;; called inclusive-OR-expression
  140. (bitwise-or-expression ; S 6.5.12
  141. (bitwise-xor-expression)
  142. (bitwise-or-expression "|" bitwise-xor-expression
  143. ($$ `(bitwise-or ,$1 ,$3))))
  144. (logical-and-expression ; S 6.5.13
  145. (bitwise-or-expression)
  146. (logical-and-expression "&&" bitwise-or-expression
  147. ($$ `(and ,$1 ,$3))))
  148. (logical-or-expression ; 6.5.14
  149. (logical-and-expression)
  150. (logical-or-expression "||" logical-and-expression
  151. ($$ `(or ,$1 ,$3))))
  152. (conditional-expression
  153. (logical-or-expression)
  154. (logical-or-expression "?" expression ":" conditional-expression
  155. ($$ `(cond-expr ,$1 ,$3 ,$5))))
  156. (assignment-expression ; S 6.5.16
  157. (conditional-expression)
  158. (unary-expression assignment-operator assignment-expression
  159. ($$ `(assn-expr ,$1 (op ,$2) ,$3))))
  160. (assignment-operator
  161. ("=") ("+=") ("-=") ("*=") ("/=") ("%=")
  162. ("<<=") (">>=") ("&=") ("^=") ("|="))
  163. (expression ; S 6.5.17
  164. (assignment-expression)
  165. (expression "," assignment-expression
  166. ($$ (if (eqv? 'comma-expr (sx-tag $1))
  167. (append $1 (list $3))
  168. `(comma-expr ,$1 ,$3)))))
  169. (constant-expression ; S 6.6
  170. (conditional-expression))
  171. ;; === declarations
  172. ;; TODO: check if we should move attributes or trap attribute-only spec's
  173. (declaration ; S 6.7
  174. (declaration-no-comment ";")
  175. (declaration-no-comment ";" code-comment ($$ (sx-attr-add $1 $3))))
  176. (declaration-no-comment
  177. (declaration-specifiers
  178. init-declarator-list
  179. ($$ (save-typenames `(decl ,$1 ,$2))))
  180. (declaration-specifiers
  181. ($$ `(decl ,$1))))
  182. ;; --- declaration specifiers
  183. (declaration-specifiers ; S 6.7
  184. (declaration-specifiers-1 ($$ (process-specs (tl->list $1)))))
  185. (declaration-specifiers-1
  186. ;; storage-class-specifiers
  187. (storage-class-specifier
  188. ($prec 'shift-on-attr) ($$ (make-tl 'decl-spec-list $1)))
  189. (storage-class-specifier declaration-specifiers-1 ($$ (tl-insert $2 $1)))
  190. ;; type-specifiers
  191. (type-specifier
  192. ($prec 'reduce-on-attr) ($$ (make-tl 'decl-spec-list $1)))
  193. (type-specifier declaration-specifiers-1 ($$ (tl-insert $2 $1)))
  194. ;; type-qualifiers
  195. (type-qualifier
  196. ($prec 'shift-on-attr) ($$ (make-tl 'decl-spec-list $1)))
  197. (type-qualifier declaration-specifiers-1 ($$ (tl-insert $2 $1)))
  198. ;; function-specifiers
  199. (function-specifier
  200. ($prec 'reduce-on-attr) ($$ (make-tl 'decl-spec-list $1)))
  201. (function-specifier declaration-specifiers-1 ($$ (tl-insert $2 $1)))
  202. ;; attribute-specifiers
  203. (attribute-specifier
  204. ($prec 'reduce-on-semi) ($$ (make-tl 'decl-spec-list $1)))
  205. (attribute-specifier declaration-specifiers-1 ($$ (tl-insert $2 $1))))
  206. (storage-class-specifier ; S 6.7.1
  207. ("auto" ($$ '(stor-spec (auto))))
  208. ("extern" ($$ '(stor-spec (extern))))
  209. ("register" ($$ '(stor-spec (register))))
  210. ("static" ($$ '(stor-spec (static))))
  211. ("typedef" ($$ '(stor-spec (typedef)))))
  212. ;; I have created fixed-, float- and complex- type specifiers to capture
  213. ;; combinations like "short int" "long long" etc.
  214. (type-specifier ; S 6.7.2
  215. ("void" ($$ '(type-spec (void))))
  216. (fixed-type-specifier ($$ `(type-spec ,$1)))
  217. (float-type-specifier ($$ `(type-spec ,$1)))
  218. (fixpt-type-specifier ($$ `(type-spec ,$1)))
  219. ("_Bool" ($$/ref 's5.1.5-01 '(type-spec (fixed-type "_Bool"))))
  220. (complex-type-specifier ($$ `(type-spec ,$1)))
  221. (struct-or-union-specifier ($$ `(type-spec ,$1)))
  222. (enum-specifier ($$ `(type-spec ,$1)))
  223. (typedef-name ($$ `(type-spec ,$1))))
  224. (fixed-type-specifier
  225. ("short" ($prec 'imp) ($$ '(fixed-type "short")))
  226. ("short" "int" ($$ '(fixed-type "short int")))
  227. ("signed" "short" ($prec 'imp) ($$ '(fixed-type "signed short")))
  228. ("signed" "short" "int" ($$ '(fixed-type "signed short int")))
  229. ("int" ($$ '(fixed-type "int")))
  230. ("signed" ($prec 'imp) ($$ '(fixed-type "signed")))
  231. ("signed" "int" ($$ '(fixed-type "signed int")))
  232. ("long" ($prec 'imp) ($$ '(fixed-type "long")))
  233. ("long" "int" ($$ '(fixed-type "long int")))
  234. ("signed" "long" ($prec 'imp) ($$ '(fixed-type "signed long")))
  235. ("signed" "long" "int" ($$ '(fixed-type "signed long int")))
  236. ("long" "long" ($prec 'imp) ($$ '(fixed-type "long long")))
  237. ("long" "long" "int" ($$ '(fixed-type "long long int")))
  238. ("signed" "long" "long" ($prec 'imp)
  239. ($$ '(fixed-type "signed long long")))
  240. ("signed" "long" "long" "int" ($$ '(fixed-type "signed long long int")))
  241. ("unsigned" "short" "int" ($$ '(fixed-type "unsigned short int")))
  242. ("unsigned" "short" ($prec 'imp) ($$ '(fixed-type "unsigned short")))
  243. ("unsigned" "int" ($$ '(fixed-type "unsigned int")))
  244. ("unsigned" ($prec 'imp) ($$ '(fixed-type "unsigned")))
  245. ("unsigned" "long" "int" ($$ '(fixed-type "unsigned long")))
  246. ("unsigned" "long" ($prec 'imp) ($$ '(fixed-type "unsigned long")))
  247. ("unsigned" "long" "long" "int"
  248. ($$ '(fixed-type "unsigned long long int")))
  249. ("unsigned" "long" "long" ($prec 'imp)
  250. ($$ '(fixed-type "unsigned long long")))
  251. ("char" ($$ '(fixed-type "char")))
  252. ("signed" "char" ($$ '(fixed-type "signed char")))
  253. ("unsigned" "char" ($$ '(fixed-type "unsigned char"))))
  254. (float-type-specifier
  255. ("float" ($prec 'imp) ($$ '(float-type "float")))
  256. ("double" ($prec 'imp) ($$ '(float-type "double")))
  257. ("long" "double" ($$ '(float-type "long double"))))
  258. (complex-type-specifier
  259. ("_Complex" ($$ '(complex-type "_Complex")))
  260. ("float" "_Complex" ($$ '(complex-type "float _Complex")))
  261. ("double" "_Complex" ($$ '(complex-type "double _Complex")))
  262. ("long" "double" "_Complex" ($$ '(complex-type "long double _Complex"))))
  263. (fixpt-type-specifier
  264. ;; http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2001/n1290.pdf
  265. ("short" "_Fract" ($$ '(fixpt-type "short _Fract")))
  266. ("_Fract" ($$ '(fixpt-type "_Fract")))
  267. ("long" "_Fract" ($$ '(fixpt-type "long _Fract")))
  268. ("signed" "short" "_Fract" ($$ '(fixpt-type "signd short _Fract")))
  269. ("signed" "_Fract" ($$ '(fixpt-type "signed _Fract")))
  270. ("signed" "long _Fract" ($$ '(fixpt-type "signed long _Fract")))
  271. ("unsigned" "short" "_Fract" ($$ '(fixpt-type "unsigned short _Fract")))
  272. ("unsigned" "_Fract" ($$ '(fixpt-type "unsigned _Fract")))
  273. ("unsigned" "long _Fract" ($$ '(fixpt-type "unsigned long _Fract")))
  274. ("short" "_Accum" ($$ '(fixpt-type "short _Accum")))
  275. ("_Accum" ($$ '(fixpt-type "_Accum")))
  276. ("long _Accum" ($$ '(fixpt-type "long _Accum")))
  277. ("signed" "short" "_Accum" ($$ '(fixpt-type "signd short _Accum")))
  278. ("signed" "_Accum" ($$ '(fixpt-type "signed _Accum")))
  279. ("signed" "long" "_Accum" ($$ '(fixpt-type "signed long _Accum")))
  280. ("unsigned" "short" "_Accum" ($$ '(fixpt-type "unsigned short _Accum")))
  281. ("unsigned" "_Accum" ($$ '(fixpt-type "unsigned _Accum")))
  282. ("unsigned" "long" "_Accum" ($$ '(fixpt-type "unsigned long _Accum")))
  283. ("_Sat" "short" "_Fract" ($$ '(fixpt-type "_Sat short _Fract")))
  284. ("_Sat" "_Fract" ($$ '(fixpt-type "_Sat _Fract")))
  285. ("_Sat" "long" "_Fract" ($$ '(fixpt-type "_Sat long _Fract")))
  286. ("_Sat" "signed" "short" "_Fract"
  287. ($$ '(fixpt-type "_Sat signd short _Fract")))
  288. ("_Sat" "signed" "_Fract" ($$ '(fixpt-type "_Sat signed _Fract")))
  289. ("_Sat" "signed" "long _Fract"
  290. ($$ '(fixpt-type "_Sat signed long _Fract")))
  291. ("_Sat" "unsigned" "short" "_Fract"
  292. ($$ '(fixpt-type "_Sat unsigned short _Fract")))
  293. ("_Sat" "unsigned" "_Fract" ($$ '(fixpt-type "_Sat unsigned _Fract")))
  294. ("_Sat" "unsigned" "long" "_Fract"
  295. ($$ '(fixpt-type "_Sat unsigned long _Fract")))
  296. ("_Sat" "short" "_Accum" ($$ '(fixpt-type "_Sat short _Accum")))
  297. ("_Sat" "_Accum" ($$ '(fixpt-type "_Sat _Accum")))
  298. ("_Sat" "long" "_Accum" ($$ '(fixpt-type "_Sat long _Accum")))
  299. ("_Sat" "signed" "short" "_Accum"
  300. ($$ '(fixpt-type "_Sat signd short _Accum")))
  301. ("_Sat" "signed" "_Accum" ($$ '(fixpt-type "_Sat signed _Accum")))
  302. ("_Sat" "signed" "long" "_Accum"
  303. ($$ '(fixpt-type "_Sat signed long _Accum")))
  304. ("_Sat" "unsigned" "short" "_Accum"
  305. ($$ '(fixpt-type "_Sat unsigned short _Accum")))
  306. ("_Sat" "unsigned" "_Accum" ($$ '(fixpt-type "_Sat unsigned _Accum")))
  307. ("_Sat" "unsigned" "long" "_Accum"
  308. ($$ '(fixpt-type "_Sat unsigned long _Accum"))))
  309. ;; This one modified: split out struct-or-union = "struct"|"union"
  310. (struct-or-union-specifier
  311. ("struct" opt-attr-specs ident-like "{" struct-declaration-list "}"
  312. ($$ (sx-join* 'struct-def $2 $3 (tl->list $5))))
  313. ("struct" opt-attr-specs "{" struct-declaration-list "}"
  314. ($$ (sx-join* 'struct-def $2 (tl->list $4))))
  315. ("struct" opt-attr-specs ident-like ($$ (sx-join* 'struct-ref $1 $3)))
  316. ("union" opt-attr-specs ident-like "{" struct-declaration-list "}"
  317. ($$ (sx-join* 'union-def $2 $3 (tl->list $5))))
  318. ("union" opt-attr-specs "{" struct-declaration-list "}"
  319. ($$ (sx-join* 'union-def $2 (tl->list $4))))
  320. ("union" opt-attr-specs ident-like ($$ (sx-join* 'union-ref $2 $3))))
  321. ;; because name following struct/union can be identifier or typeref:
  322. (ident-like
  323. (identifier)
  324. (typedef-name ($$ `(ident ,(sx-ref $1 1)))))
  325. (opt-attr-specs
  326. ($empty)
  327. (attribute-specifiers ($$ `(@ ,(attrl->attrs $1)))))
  328. ;; Calling this field-list in the parse tree.
  329. (struct-declaration-list ; S 6.7.2.1
  330. (struct-declaration ($$ (make-tl 'field-list $1)))
  331. (lone-comment ($$ (make-tl 'field-list $1)))
  332. (struct-declaration-list struct-declaration ($$ (tl-append $1 $2)))
  333. (struct-declaration-list lone-comment ($$ (tl-append $1 $2)))
  334. ;; Not in C99, but allowed by GNU, I believe:
  335. (";" ($$ (make-tl 'field-list)))
  336. (struct-declaration-list ";" ($$ $1)))
  337. (struct-declaration ; S 6.7.2.1
  338. (struct-declaration-no-comment ";")
  339. (struct-declaration-no-comment ";" code-comment ($$ (sx-attr-add $1 $3))))
  340. (struct-declaration-no-comment
  341. (specifier-qualifier-list
  342. struct-declarator-list ($$ `(comp-decl ,$1 ,(tl->list $2))))
  343. (specifier-qualifier-list ($$ `(comp-decl ,$1)))) ;; <= anonymous
  344. (specifier-qualifier-list ; S 6.7.2.1
  345. (specifier-qualifier-list-1 ($$ (process-specs (tl->list $1)))))
  346. (specifier-qualifier-list-1
  347. (type-specifier ($$ (make-tl 'decl-spec-list $1)))
  348. (type-specifier specifier-qualifier-list-1 ($$ (tl-insert $2 $1)))
  349. (type-qualifier ($$ (make-tl 'decl-spec-list $1)))
  350. (type-qualifier specifier-qualifier-list-1 ($$ (tl-insert $2 $1)))
  351. (attribute-specifier ($$ (make-tl 'decl-spec-list $1)))
  352. (attribute-specifier specifier-qualifier-list-1 ($$ (tl-insert $2 $1))))
  353. (specifier-qualifier-list/no-attr
  354. (specifier-qualifier-list/no-attr-1 ($$ (tl->list $1))))
  355. (specifier-qualifier-list/no-attr-1
  356. (type-specifier ($$ (make-tl 'decl-spec-list $1)))
  357. (type-specifier specifier-qualifier-list/no-attr-1 ($$ (tl-insert $2 $1)))
  358. (type-qualifier ($$ (make-tl 'decl-spec-list $1)))
  359. (type-qualifier specifier-qualifier-list/no-attr-1 ($$ (tl-insert $2 $1))))
  360. (struct-declarator-list ; S 6.7.2.1
  361. (struct-declarator ($$ (make-tl 'comp-declr-list $1)))
  362. (struct-declarator-list "," struct-declarator ($$ (tl-append $1 $3)))
  363. (struct-declarator-list "," attribute-specifiers
  364. struct-declarator ($$ (tl-append $1 $3 $4))))
  365. (struct-declarator ; S 6.7.2.1
  366. (struct-declarator-1 ($$ (process-declr $1))))
  367. (struct-declarator-1
  368. (declarator ($$ `(comp-declr ,$1)))
  369. (declarator attribute-specifiers ($$ `(comp-declr ,$1 ,$2)))
  370. (declarator ":" constant-expression
  371. ($$ `(comp-declr (bit-field ,$1 ,$3))))
  372. (":" constant-expression ($$ `(comp-declr (bit-field ,$2)))))
  373. (enum-specifier ; S 6.7.2.2
  374. ("enum" ident-like "{" enumerator-list "}"
  375. ($$ `(enum-def ,$2 ,(tl->list $4))))
  376. ("enum" ident-like "{" enumerator-list "," "}"
  377. ($$ `(enum-def ,$2 ,(tl->list $4))))
  378. ("enum" "{" enumerator-list "}" ($$ `(enum-def ,(tl->list $3))))
  379. ("enum" "{" enumerator-list "," "}" ($$ `(enum-def ,(tl->list $3))))
  380. ("enum" ident-like ($$ `(enum-ref ,$2))))
  381. ;; keeping old enum-def-list in parse tree
  382. (enumerator-list ; S 6.7.2.2
  383. (enumerator ($$ (make-tl 'enum-def-list $1)))
  384. (enumerator-list "," enumerator ($$ (tl-append $1 $3))))
  385. ;; had to change enumeration-constant => identifier
  386. (enumerator ; S 6.7.2.2
  387. (identifier ($$ `(enum-defn ,$1)))
  388. (identifier attribute-specifiers ($$ `(enum-defn ,$1 ,$2)))
  389. (identifier "=" constant-expression ($$ `(enum-defn ,$1 ,$3))))
  390. (type-qualifier
  391. ("const" ($$ `(type-qual ,$1)))
  392. ("volatile" ($$ `(type-qual ,$1)))
  393. ("restrict" ($$ `(type-qual ,$1))))
  394. (function-specifier
  395. ("inline" ($$ `(fctn-spec ,$1)))
  396. ("_Noreturn" ($$ `(fctn-spec ,$1))))
  397. ;; Support for __attribute__(( ... )). See the gcc documentation.
  398. ;; The documentation does not seem rigourous about defining where the
  399. ;; attribute specifier can appear. This is my best attempt. MW 2018
  400. ;; https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/Attribute-Syntax.html
  401. ;; https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/Type-Attributes.html
  402. ;; https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/Variable-Attributes.html
  403. ;; https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/Function-Attributes.html
  404. (attribute-specifiers
  405. (attribute-specifier ($prec 'reduce-on-attr))
  406. (attribute-specifiers attribute-specifier ($$ (append $1 (cdr $2)))))
  407. ;; (attributes (attribute "__static__") (attribute aligned(8)" ...)
  408. (attribute-specifier
  409. ("__attribute__" "(" "(" attribute-list ")" ")" ($$ $4))
  410. (attr-name ($$ `(attribute-list (attribute ,$1)))))
  411. (attr-name
  412. ("__packed__" ($$ '(ident "__packed__")))
  413. ("__aligned__" ($$ '(ident "__aligned__")))
  414. ("__alignof__" ($$ '(ident "__alignof__"))))
  415. (attribute-list (attribute-list-1 ($$ (tl->list $1))))
  416. (attribute-list-1
  417. (attribute ($$ (make-tl 'attribute-list $1)))
  418. (attribute-list-1 "," attribute ($$ (tl-append $1 $3)))
  419. (attribute-list-1 "," ($$ $1)))
  420. (attribute
  421. (attr-word ($$ `(attribute ,$1)))
  422. (attr-word "(" attr-expr-list ")" ($$ `(attribute ,$1 ,$3)))
  423. ("const" ($$ `(attribute (ident "const")))))
  424. (attr-word
  425. (attr-name)
  426. (identifier))
  427. (attr-expr-list
  428. (attr-expr-list-1 ($$ (tl->list $1))))
  429. (attr-expr-list-1
  430. (attribute-expr ($$ (make-tl 'attr-expr-list $1)))
  431. (attr-expr-list-1 "," attribute-expr ($$ (tl-append $1 $3))))
  432. (attribute-expr
  433. (type-name)
  434. ($fixed ($$ `(fixed ,$1)))
  435. (string-literal)
  436. (identifier)
  437. (attr-word "(" attr-expr-list ")" ($$ `(attribute ,$1 ,$3)))) ;; ???
  438. ;; --- declarators
  439. (init-declarator-list ; S 6.7
  440. (init-declarator-list-1 ($$ (tl->list $1))))
  441. (init-declarator-list-1
  442. (init-declarator ($$ (make-tl 'init-declr-list $1)))
  443. (init-declarator-list-1 "," init-declarator ($$ (tl-append $1 $3)))
  444. (init-declarator-list-1 "," attribute-specifiers
  445. init-declarator ($$ (tl-append $1 $3 $4))))
  446. (init-declarator ; S 6.7
  447. (init-declarator-1 ($$ (process-declr $1))))
  448. (init-declarator-1
  449. (declarator ($$ `(init-declr ,$1)))
  450. (declarator "=" initializer ($$ `(init-declr ,$1 ,$3)))
  451. (declarator asm-expression ($$ `(init-declr ,$1 ,$2)))
  452. (declarator asm-expression "=" initializer ($$ `(init-declr ,$1 ,$2 ,$4)))
  453. (declarator attribute-specifiers ($$ `(init-declr ,$1 ,$2)))
  454. (declarator attribute-specifiers "=" initializer
  455. ($$ `(init-declr ,$1 ,$2 ,$4)))
  456. (declarator asm-expression attribute-specifiers
  457. ($$ `(init-declr ,$1 ,$2 ,$3))))
  458. (declarator
  459. (pointer direct-declarator ($$ `(ptr-declr ,$1 ,$2)))
  460. (direct-declarator))
  461. (pointer ; S 6.7.6
  462. ("*" type-qualifier-list pointer ($$ `(pointer ,$2 ,$3)))
  463. ("*" type-qualifier-list ($$ `(pointer ,$2)))
  464. ("*" pointer ($$ `(pointer ,$2)))
  465. ("*" attribute-specifiers pointer ($$ `(pointer ,$3)))
  466. ("*" ($$ '(pointer))))
  467. (direct-declarator ; S 6.7.6
  468. (identifier ($$ $1))
  469. ;;(ident-like ($$ $1))
  470. ("(" declarator ")" ($$ `(scope ,$2)))
  471. ("(" attribute-specifier declarator ")" ($$ `(scope ,$2)))
  472. (direct-declarator
  473. "[" type-qualifier-list assignment-expression "]"
  474. ($$ `(array-of ,$1 ,$3 ,$4)))
  475. (direct-declarator
  476. "[" type-qualifier-list "]" ($$ `(array-of ,$1 ,$3)))
  477. (direct-declarator
  478. "[" assignment-expression "]" ($$ `(array-of ,$1 ,$3)))
  479. (direct-declarator
  480. "[" "]" ($$ `(array-of ,$1)))
  481. (direct-declarator
  482. "[" "static" type-qualifier-list assignment-expression "]"
  483. ($$ `(array-of ,$1 ,$4 ,$5))) ;; FIXME $4 needs "static" added
  484. (direct-declarator
  485. "[" type-qualifier-list "static" assignment-expression "]"
  486. ($$ `(array-of ,$1 ,4 ,$5))) ;; FIXME $4 needs "static" added
  487. (direct-declarator
  488. "[" type-qualifier-list "*" "]" ; variable length array
  489. ($$ `(array-of ,$1 ,$3 (var-len))))
  490. (direct-declarator
  491. "[" "*" "]" ; variable length array
  492. ($$ `(array-of ,$1 (var-len))))
  493. (direct-declarator
  494. "(" parameter-type-list ")" ($$ `(ftn-declr ,$1 ,$3)))
  495. (direct-declarator
  496. "(" identifier-list ")" ($$ `(ftn-declr ,$1 ,$3)))
  497. (direct-declarator
  498. "(" ")" ($$ `(ftn-declr ,$1 (param-list)))))
  499. (type-qualifier-list
  500. (type-qualifier-list-1 ($$ (tl->list $1))))
  501. (type-qualifier-list-1
  502. (type-qualifier ($$ (make-tl 'type-qual-list $1)))
  503. (type-qualifier-list-1 type-qualifier ($$ (tl-append $1 $2))))
  504. (parameter-type-list
  505. (parameter-list ($$ (tl->list $1)))
  506. (parameter-list "," "..." ($$ (tl->list (tl-append $1 '(ellipsis))))))
  507. (parameter-list
  508. (parameter-declaration ($$ (make-tl 'param-list $1)))
  509. (parameter-list "," parameter-declaration ($$ (tl-append $1 $3))))
  510. (parameter-declaration
  511. (declaration-specifiers
  512. declarator ($$ `(param-decl ,$1 (param-declr ,$2))))
  513. (declaration-specifiers
  514. abstract-declarator ($$ `(param-decl ,$1 (param-declr ,$2))))
  515. (declaration-specifiers
  516. ($$ `(param-decl ,$1))))
  517. (identifier-list
  518. (identifier-list-1 ($$ (tl->list $1))))
  519. (identifier-list-1
  520. (identifier ($$ (make-tl 'ident-list $1)))
  521. (identifier-list-1 "," identifier ($$ (tl-append $1 $3))))
  522. (type-name ; S 6.7.6
  523. ;; e.g., (foo_t *)
  524. (specifier-qualifier-list/no-attr abstract-declarator
  525. ($$ `(type-name ,$1 ,$2)))
  526. ;; e.g., (int)
  527. (declaration-specifiers ($$ `(type-name ,$1))))
  528. (abstract-declarator ; S 6.7.6
  529. (pointer direct-abstract-declarator ($$ `(abs-declr ,$1 ,$2)))
  530. (pointer ($$ `(abs-declr ,$1)))
  531. (direct-abstract-declarator ($$ `(abs-declr ,$1))))
  532. (direct-abstract-declarator
  533. ("(" abstract-declarator ")" ($$ `(declr-scope ,$2)))
  534. (direct-abstract-declarator
  535. "[" type-qualifier-list assignment-expression "]"
  536. ($$ `(declr-array ,$1 ,$3 ,$4)))
  537. (direct-abstract-declarator
  538. "[" type-qualifier-list "]"
  539. ($$ `(declr-array ,$1 ,$3)))
  540. (direct-abstract-declarator
  541. "[" assignment-expression "]"
  542. ($$ `(declr-array ,$1 ,$3)))
  543. (direct-abstract-declarator
  544. "[" "]" ($$ `(declr-array ,$1)))
  545. (direct-abstract-declarator
  546. "[" "static" type-qualifier-list assignment-expression "]"
  547. ($$ `(declr-array
  548. ,$1 ,(tl->list (tl-insert $4 '(stor-spec "static"))) ,$5)))
  549. (direct-abstract-declarator
  550. "[" "static" type-qualifier-list "]"
  551. ($$ `(declr-array ,$1 ,(tl->list (tl-insert $4 '(stor-spec "static"))))))
  552. (direct-abstract-declarator
  553. "[" type-qualifier-list "static" assignment-expression "]"
  554. ($$ `(declr-array
  555. ,$1 ,(tl->list (tl-insert $3 '(stor-spec "static"))) ,$5)))
  556. ;;
  557. ("[" type-qualifier-list assignment-expression "]"
  558. ($$ `(declr-anon-array ,$2 ,$3)))
  559. ("[" type-qualifier-list "]" ($$ `(declr-anon-array ,$2)))
  560. ("[" assignment-expression "]" ($$ `(declr-anon-array ,$2)))
  561. ("[" "]" ($$ `(declr-anon-array)))
  562. ("[" "static" type-qualifier-list assignment-expression "]"
  563. ($$ `(declr-anon-array
  564. ,(tl->list (tl-insert $3 '(stor-spec "static"))) ,$4)))
  565. ("[" "static" type-qualifier-list "]"
  566. ($$ `(declr-anon-array ,(tl->list (tl-insert $3 '(stor-spec "static"))))))
  567. ("[" type-qualifier-list "static" assignment-expression "]"
  568. ($$ `(declr-anon-array
  569. ,(tl->list (tl-insert $2 '(stor-spec "static"))) ,$4)))
  570. (direct-abstract-declarator "[" "*" "]" ($$ `(declr-star ,$1)))
  571. ("[" "*" "]" ($$ '(declr-star)))
  572. (direct-abstract-declarator "(" parameter-type-list ")"
  573. ($$ `(abs-ftn-declr ,$1 ,$3)))
  574. (direct-abstract-declarator "(" ")" ($$ `(abs-ftn-declr ,$1)))
  575. ("(" parameter-type-list ")" ($$ `(anon-ftn-declr ,$2)))
  576. ("(" ")" ($$ '(anon-ftn-declr))))
  577. ;; typedef-name is generated by the lexical analyzer
  578. (typedef-name ('typename ($$ `(typename ,$1))))
  579. ;; --------------------------------
  580. (initializer ; S 6.7.9
  581. (assignment-expression ($$ `(initzer ,$1)))
  582. ("{" initializer-list "}" ($$ `(initzer ,(tl->list $2))))
  583. ("{" initializer-list "," "}" ($$ `(initzer ,(tl->list $2)))))
  584. ;; The designation productions are from C99.
  585. (initializer-list
  586. (designation initializer ($$ (make-tl 'initzer-list $1 $2)))
  587. (initializer ($$ (make-tl 'initzer-list $1)))
  588. (initializer-list "," designation initializer ($$ (tl-append $1 $3 $4)))
  589. (initializer-list "," initializer ($$ (tl-append $1 $3))))
  590. (designation ; S 6.7.8
  591. (designator-list "=" ($$ `(desig ,$1))))
  592. (designator-list
  593. (designator ($$ (make-tl 'desgr-list $1)))
  594. (designator-list designator ($$ (tl-append $1 $2))))
  595. (designator
  596. ("[" constant-expression "]" ($$ `(array-dsgr ,$2)))
  597. ("." identifier ($$ `(sel-dsgr ,$2))))
  598. ;; === statements =========================================================
  599. (statement
  600. (labeled-statement)
  601. (compound-statement)
  602. (expression-statement)
  603. (selection-statement)
  604. (iteration-statement)
  605. (jump-statement)
  606. (asm-statement)
  607. (pragma)
  608. (cpp-statement))
  609. (labeled-statement
  610. (identifier ":" statement ($$ `(labeled-stmt ,$1 ,$3)))
  611. (identifier ":" attribute-specifier statement
  612. ($$ `(labeled-stmt ,$1 ,$4)))
  613. ("case" constant-expression ":" statement ($$ `(case ,$2 ,$4)))
  614. ("default" ":" statement ($$ `(default ,$3))))
  615. (compound-statement
  616. ("{" ($$ (cpi-push)) block-item-list ($$ (cpi-pop)) "}"
  617. ($$ `(compd-stmt ,(tl->list $3))))
  618. ("{" "}"
  619. ($$ `(compd-stmt (block-item-list)))))
  620. (block-item-list
  621. (block-item ($$ (make-tl 'block-item-list $1)))
  622. (block-item-list block-item ($$ (tl-append $1 $2))))
  623. (block-item
  624. (declaration)
  625. (statement))
  626. (expression-statement
  627. (expression ";" ($$ `(expr-stmt ,$1)))
  628. (";" ($$ '(expr-stmt))))
  629. (selection-statement
  630. ("if" "(" expression ")" statement ($prec 'then)
  631. ($$ `(if ,$3 ,$5)))
  632. ("if" "(" expression ")" statement "else" statement
  633. ($$ `(if ,$3 ,$5 ,$7)))
  634. ("switch" "(" expression ")" statement ($$ `(switch ,$3 ,$5))))
  635. (iteration-statement
  636. ("while" "(" expression ")" statement ($$ `(while ,$3 ,$5)))
  637. ("do" statement "while" "(" expression ")" ";" ($$ `(do-while ,$2 ,$5)))
  638. ("for" "(" initial-clause opt-expression ";" opt-expression ")" statement
  639. ($$ `(for ,$3 ,$4 ,$6 ,$8))))
  640. (initial-clause ; <= added for convenience
  641. (expression ";")
  642. (";" ($$ '(expr)))
  643. (declaration))
  644. (opt-expression ; <= added for convenience
  645. ($empty ($$ '(expr)))
  646. (expression))
  647. (jump-statement ; S 6.8.6
  648. ("goto" identifier ";" ($$ `(goto ,$2)))
  649. ("continue" ";" ($$ '(continue)))
  650. ("break" ";" ($$ '(break)))
  651. ("return" expression ";" ($$ `(return ,$2)))
  652. ("return" ";" ($$ `(return (expr)))))
  653. (asm-statement
  654. (asm-expression ";"))
  655. (asm-expression
  656. ("__asm__" opt-asm-specifiers "(" string-literal ")"
  657. ($$ `(asm-expr (@ (extension "GNUC")) ,$4)))
  658. ("__asm__" opt-asm-specifiers "(" string-literal asm-outputs ")"
  659. ($$ `(asm-expr (@ (extension "GNUC")) ,$4 ,(tl->list $5))))
  660. ("__asm__" opt-asm-specifiers "(" string-literal asm-outputs asm-inputs ")"
  661. ($$ `(asm-expr (@ (extension "GNUC")) ,$4 ,(tl->list $5) ,(tl->list $6))))
  662. ("__asm__" opt-asm-specifiers "(" string-literal asm-outputs
  663. asm-inputs asm-clobbers ")"
  664. ($$ `(asm-expr (@ (extension "GNUC"))
  665. ,$4 ,(tl->list $5) ,(tl->list $6) ,(tl->list $7)))))
  666. (opt-asm-specifiers
  667. ($empty)
  668. ("volatile"))
  669. (asm-outputs
  670. (":" ($$ (make-tl 'asm-outputs)))
  671. (":" asm-output ($$ (make-tl 'asm-outputs $2)))
  672. (asm-outputs "," asm-output ($$ (tl-append $1 $3))))
  673. (asm-output
  674. (string-literal "(" identifier ")" ($$ `(asm-operand ,$1 ,$3)))
  675. ("[" identifier "]" string-literal "(" identifier ")"
  676. ($$ `(asm-operand ,$2 ,$4 ,$6))))
  677. (asm-inputs
  678. (":" ($$ (make-tl 'asm-inputs)))
  679. (":" asm-input ($$ (make-tl 'asm-inputs $2)))
  680. (asm-inputs "," asm-input ($$ (tl-append $1 $3))))
  681. (asm-input
  682. (string-literal "(" expression ")" ($$ `(asm-operand ,$1 ,$3)))
  683. ("[" identifier "]" string-literal "(" expression ")"
  684. ($$ `(asm-operand ,$2 ,$4 ,$6))))
  685. (asm-clobbers
  686. (":" ($$ (make-tl 'asm-clobbers)))
  687. (":" string-literal ($$ (tl-extend (make-tl 'asm-clobbers) $2)))
  688. (asm-clobbers "," string-literal ($$ (tl-extend $1 (cdr $3)))))
  689. ;; === top-level forms ====================================================
  690. (translation-unit ; S 6.9
  691. (external-declaration-list ($$ (tl->list $1))))
  692. (external-declaration-list
  693. ($empty ($$ (make-tl 'trans-unit)))
  694. (external-declaration-list
  695. external-declaration
  696. ;; A ``kludge'' to deal with @code{extern "C" ...}:
  697. ($$ (if (eqv? (sx-tag $2) 'extern-block)
  698. (tl-extend $1 (sx-tail $2 1))
  699. (tl-append $1 $2)))))
  700. (external-declaration ; S 6.9
  701. (function-definition)
  702. (declaration)
  703. (lone-comment)
  704. (cpp-statement)
  705. (pragma)
  706. ("extern" $string "{"
  707. ($$ (cpi-dec-blev!)) external-declaration-list ($$ (cpi-inc-blev!)) "}"
  708. ($$ `(extern-block
  709. (extern-begin ,$2) ,@(sx-tail (tl->list $5) 1) (extern-end))))
  710. (";" ($$ `(decl (@ (extension "GNUC"))))))
  711. (function-definition
  712. (declaration-specifiers
  713. declarator compound-statement
  714. ($$ `(fctn-defn ,$1 ,$2 ,$3)))
  715. ;; K&R function definitions are not compatible with attribute-specifiers.
  716. ;;(declaration-specifiers
  717. ;; declarator declaration-list compound-statement
  718. ;; ($$ `(knr-fctn-defn ,$1 ,$2 ,$3 ,$4)))
  719. )
  720. ;; K&R function-definition parameter list
  721. ;;(declaration-list (declaration-list-1 ($$ (tl->list $1))))
  722. ;;(declaration-list-1
  723. ;; (declaration ($$ (make-tl 'decl-list $1)))
  724. ;; (declaration-list-1 declaration ($$ (tl-append $1 $2))))
  725. ;; non-terminal leaves
  726. (identifier ($ident ($$ `(ident ,$1))))
  727. (constant
  728. ($fixed ($$ `(fixed ,$1))) ; integer literal
  729. ($float ($$ `(float ,$1))) ; floating literal
  730. ($chlit ($$ `(char ,$1))) ; char literal
  731. ($chlit/L ($$ `(char (@ (type "wchar_t")) ,$1)))
  732. ($chlit/u ($$ `(char (@ (type "char16_t")) ,$1)))
  733. ($chlit/U ($$ `(char (@ (type "char32_t")) ,$1))))
  734. (string-literal (string-literal-1 ($$ (tl->list $1))))
  735. (string-literal-1
  736. ($string ($$ (make-tl 'string $1))) ; string-constant
  737. (string-literal-1 $string ($$ (tl-append $1 $2))))
  738. (code-comment ($code-comm ($$ `(comment ,$1))))
  739. (lone-comment ($lone-comm ($$ `(comment ,$1))))
  740. (cpp-statement ('cpp-stmt ($$ `(cpp-stmt ,$1))))
  741. (pragma
  742. ($pragma ($$ `(pragma ,$1)))
  743. ("_Pragma" "(" string-literal ")" ($$ `(pragma ,$3))))
  744. )))
  745. ;;; === parsers =========================
  746. ;; We setup dev parser because circular dependence between lexer and parser
  747. ;; due to parsing include files as units for code and decl mode.
  748. ;; update: This is doable now (see parser.scm) but wait until it's needed.
  749. (define c99-mach
  750. (compact-machine
  751. (hashify-machine
  752. (make-lalr-machine c99-spec))
  753. #:keep 2
  754. #:keepers '($code-comm $lone-comm $pragma)))
  755. (define c99x-spec (restart-spec c99-spec 'expression))
  756. (define c99x-mach
  757. (compact-machine
  758. (hashify-machine
  759. (make-lalr-machine c99x-spec))
  760. #:keep 2
  761. #:keepers '($code-comm $lone-comm $pragma)))
  762. ;;; =====================================
  763. ;; @deffn {Procedure} gen-c99-files [dir] => #t
  764. ;; Update or generate the files @quot{c99act.scm} and @quot{c99tab.scm}.
  765. ;; These are the tables and actions for the C99 parser.
  766. ;; If there are no changes to existing files, no update occurs.
  767. ;; @end deffn
  768. (define* (gen-c99-files #:optional (path "."))
  769. (define (mdir file) (mach-dir path file))
  770. (write-lalr-actions c99-mach (mdir "c99-act.scm.new") #:prefix "c99-")
  771. (write-lalr-tables c99-mach (mdir "c99-tab.scm.new") #:prefix "c99-")
  772. (write-lalr-actions c99x-mach (mdir "c99x-act.scm.new") #:prefix "c99x-")
  773. (write-lalr-tables c99x-mach (mdir "c99x-tab.scm.new") #:prefix "c99x-")
  774. (let ((a (move-if-changed (mdir "c99-act.scm.new") (mdir "c99-act.scm")))
  775. (b (move-if-changed (mdir "c99-tab.scm.new") (mdir "c99-tab.scm")))
  776. (c (move-if-changed (mdir "c99x-act.scm.new") (mdir "c99x-act.scm")))
  777. (d (move-if-changed (mdir "c99x-tab.scm.new") (mdir "c99x-tab.scm"))))
  778. (or a b c d)))
  779. ;; --- last line ---