
https://svn.lrde.epita.fr/svn/xrm/trunk Index: ChangeLog from SIGOURE Benoit <sigoure.benoit@lrde.epita.fr> Improve desugarisation, fix concrete syntax. * src/str/xrm-front.str: Remove empty line. * src/str/prism-desugar.meta: New. * src/str/Makefile.am: Update header. * src/str/prism-desugar.str: Use concrete syntax. Improve and simplify desugarisation. Extend to doubles. * src/str/reals.str: New. * src/syn/xrm/Makefile.am: Add parse table generation for concrete syntax. * src/syn/prism/Makefile.am: Likewise. * src/syn/prism/PRISM-MetaVars.sdf: Fix meta-vars. * src/syn/prism/PRISM-Identifier.sdf: Fix restrictions. str/Makefile.am | 4 - str/prism-desugar.meta | 1 str/prism-desugar.str | 111 ++++++++++++++++++++--------------------- str/reals.str | 27 +++++++++ str/xrm-front.str | 1 syn/prism/Makefile.am | 5 + syn/prism/PRISM-Identifier.sdf | 4 + syn/prism/PRISM-MetaVars.sdf | 7 +- syn/xrm/Makefile.am | 5 + 9 files changed, 98 insertions(+), 67 deletions(-) Index: src/str/xrm-front.str --- src/str/xrm-front.str (revision 23) +++ src/str/xrm-front.str (working copy) @@ -113,7 +113,6 @@ must-desugar = <get-config> "desugar" => "yes" - /** * Documentation */ Index: src/str/prism-desugar.meta --- src/str/prism-desugar.meta (revision 0) +++ src/str/prism-desugar.meta (revision 0) @@ -0,0 +1 @@ +Meta([Syntax("StrategoXRM")]) Index: src/str/Makefile.am --- src/str/Makefile.am (revision 23) +++ src/str/Makefile.am (working copy) @@ -1,11 +1,11 @@ ## -## Makefile.am for xrm in /home/tsuna/work/xrm/trunk/src +## Makefile.am for xrm in /home/tsuna/work/xrm/trunk/src/str ## ## Made by SIGOURE Benoit ## Mail <sigoure.benoit@lrde.epita.fr> ## ## Started on Thu Apr 27 17:59:35 2006 SIGOURE Benoit -## Last update Fri May 12 16:55:22 2006 SIGOURE Benoit +## Last update Thu May 18 16:49:50 2006 SIGOURE Benoit ## include $(top_srcdir)/config/Transformers.mk Index: src/str/prism-desugar.str --- src/str/prism-desugar.str (revision 23) +++ src/str/prism-desugar.str (working copy) @@ -1,15 +1,48 @@ module prism-desugar -imports PRISM +imports + PRISM + reals strategies + /** + ** 1. First convert all literal ints to doubles. This makes the + ** simplifications easier to write since there is less cases to + ** address (eg: int + int, int + double, double + int, + ** double + double etc.). + ** 2. Desugar the AST + ** 3. Convert the doubles which are round numbers back to ints. + ** Simplify doubles (round them up and remove trailing zeros) + */ prism-desugar = - innermost( + topdown(try(IntToDouble)) + ; innermost( RemoveUnconditionnalUpdates - <+ AddZero <+ MulOne <+ MulZero <+ DivOne <+ warn-div-by-zero + <+ AddZero <+ MulOne <+ MulZero <+ DivOne <+ catch-div-by-zero <+ EvalPlus <+ EvalMinus <+ EvalMul <+ EvalDiv <+ EvalLt <+ EvalLtEq <+ EvalGt <+ EvalGtEq <+ EvalEq <+ EvalNeq ) + ; topdown(try(SimplifyDoubles <+ TruncateDouble)) + +rules + + IntToDouble: Int(i) -> Double(i) + + // Transform a round (or almost round) Double into an Int. + SimplifyDoubles: + Double(d) -> Int(i) // eg: Double("41.9999999999999") -> Int("42") + where !d // "41.9999999999999" + ; string-to-real // 4.199999999999990e+01 + ; real-to-string(|6) // "42.000000" + ; split-at-dot // ("42", "000000") + ; (?i, ?decimals) // i="42", decimals="000000" + // strcmp(decimals, "000000") == 0 ? id : fail + ; <strcmp> (<explode-string> decimals, <explode-string> "000000") => 0 + + // Round real numbers up to 6 digits and remove trailing zeros + TruncateDouble: + Double(d) -> Double(d') + where <rtrim-chars(?'0')> (<real-to-string(|6)> (<string-to-real> d)) => d' rules @@ -30,89 +63,55 @@ // used by the rules below to evaluate constant comparisons compare(s) = if s then !True() else !False() end - // for some reason the following rules are only defined for integers - // in the stratego-lib. Here is their equivalant for reals. - // NOTE: We only keep 6 digits after the period - addR = (string-to-real, string-to-real); addr; real-to-string(|6) - subtR = (string-to-real, string-to-real); subtr; real-to-string(|6) - mulR = (string-to-real, string-to-real); mulr; real-to-string(|6) - divR = (string-to-real, string-to-real); divr; real-to-string(|6) - - warn-div-by-zero = - ?Div(e, Int("0")); fatal-err-msg(|"Division by zero") + catch-div-by-zero = + ?|[ e / 0 ]|; fatal-err-msg(|"Division by zero detected") rules AddZero: - Plus(e, Int("0")) -> e + |[ e + 0 ]| -> |[ e ]| AddZero: - Plus(Int("0"), e) -> e + |[ 0 + e ]| -> |[ e ]| MulOne: - Mul(e, Int("1")) -> e + |[ e * 1 ]| -> |[ e ]| MulOne: - Mul(Int("1"), e) -> e + |[ 1 * e ]| -> |[ e ]| MulZero: - Mul(e, Int("0")) -> Int("0") + |[ e * 0 ]| -> |[ 0 ]| MulZero: - Mul(Int("0"), e) -> Int("0") + |[ 0 * e ]| -> |[ 0 ]| DivOne: - Div(e, Int("1")) -> e + |[ e / 1 ]| -> |[ e ]| EvalPlus: - Plus(Int(i), Int(j)) -> Int(<addS>(i, j)) - EvalPlus: - Plus(Double(i), Int(j)) -> Double(<addR>(i, j)) - EvalPlus: - Plus(Int(i), Double(j)) -> Double(<addR>(i, j)) - EvalPlus: - Plus(Double(i), Double(j)) -> Double(<addR>(i, j)) + |[ d1 + d2 ]| -> |[ r ]| where <addR>(d1, d2) => r EvalMinus: - Minus(Int(i), Int(j)) -> Int(<subtS>(i, j)) - EvalMinus: - Minus(Double(i), Int(j)) -> Double(<subtR>(i, j)) - EvalMinus: - Minus(Int(i), Double(j)) -> Double(<subtR>(i, j)) - EvalMinus: - Minus(Double(i), Double(j)) -> Double(<subtR>(i, j)) + |[ d1 - d2 ]| -> |[ r ]| where <subtR>(d1, d2) => r EvalMul: - Mul(Int(i), Int(j)) -> Int(<mulS>(i, j)) - EvalMul: - Mul(Double(i), Int(j)) -> Double(<mulR>(i, j)) - EvalMul: - Mul(Int(i), Double(j)) -> Double(<mulR>(i, j)) - EvalMul: - Mul(Double(i), Double(j)) -> Double(<mulR>(i, j)) + |[ d1 * d2 ]| -> |[ r ]| where <mulR>(d1, d2) => r EvalDiv: - Div(Int(i), Int(j)) -> Double(<divR>(i, j)) - EvalDiv: - Div(Double(i), Int(j)) -> Double(<divR>(i, j)) - EvalDiv: - Div(Int(i), Double(j)) -> Double(<divR>(i, j)) - EvalDiv: - Div(Double(i), Double(j)) -> Double(<divR>(i, j)) - - // FIXME: considere adding the Double's in the following: + |[ d1 / d2 ]| -> |[ r ]| where <divR>(d1, d2) => r EvalLt: - Lt(Int(i), Int(j)) -> <compare(ltS)>(i, j) + |[ d1 < d2 ]| -> <compare(ltR)>(d1, d2) EvalLtEq: - LtEq(Int(i), Int(j)) -> <compare(leqS)>(i, j) + |[ d1 <= d2 ]| -> <compare(leqR)>(d1, d2) EvalGt: - Gt(Int(i), Int(j)) -> <compare(gtS)>(i, j) + |[ d1 > d2 ]| -> <compare(gtR)>(d1, d2) EvalGtEq: - GtEq(Int(i), Int(j)) -> <compare(geqS)>(i, j) + |[ d1 >= d2 ]| -> <compare(geqR)>(d1, d2) EvalEq: - Eq(Int(i), Int(j)) -> <compare(eq)>(i, j) + |[ d1 = d2 ]| -> <compare(real-eq)>(d1, d2) EvalNeq: - NotEq(Int(i), Int(j)) -> <compare(not(eq))>(i, j) + |[ d1 != d2 ]| -> <compare(not(real-eq))>(d1, d2) Index: src/str/reals.str --- src/str/reals.str (revision 0) +++ src/str/reals.str (revision 0) @@ -0,0 +1,27 @@ +module reals + +strategies + + // for some reason the following rules are only defined for integers + // in the stratego-lib. Here is their equivalant for reals. + addR = (string-to-real, string-to-real); addr; real-to-string + subtR = (string-to-real, string-to-real); subtr; real-to-string + mulR = (string-to-real, string-to-real); mulr; real-to-string + divR = (string-to-real, string-to-real); divr; real-to-string + gtR = where((string-to-real, string-to-real); gtr) + geqR = where((string-to-real, string-to-real); ?(x,x) <+ gtr) + ltR = where((string-to-real, string-to-real); not(?(x,x) <+ gtr)) + leqR = where((string-to-real, string-to-real); not(gtr)) + + /** + ** tests whether two reals are equal + ** => tests if there difference is less than 10^-7 + ** operates on the input term (a, b) + ** eg: <real-eq> ("0.42", "0.43") -> fail + */ + real-eq = + (string-to-real, string-to-real) + ; subtr + ; abs => difference + ; <not(gtr)>(difference, 0.0000001) + Index: src/syn/xrm/Makefile.am --- src/syn/xrm/Makefile.am (revision 23) +++ src/syn/xrm/Makefile.am (working copy) @@ -5,7 +5,7 @@ ## Mail <sigoure.benoit@lrde.epita.fr> ## ## Started on Thu Apr 27 17:40:41 2006 SIGOURE Benoit -## Last update Fri May 12 16:57:54 2006 SIGOURE Benoit +## Last update Thu May 18 16:53:05 2006 SIGOURE Benoit ## include $(top_srcdir)/config/Transformers.mk @@ -28,7 +28,8 @@ XRM.str \ XRM-StartSymbols.tbl \ XRM-Prefixed.def \ - StrategoXRM.def + StrategoXRM.def \ + StrategoXRM.tbl pkgdata_DATA = $(pkgdata_DATA_built) sdfdata_DATA = $(pkgdata_DATA_built) Index: src/syn/prism/PRISM-MetaVars.sdf --- src/syn/prism/PRISM-MetaVars.sdf (revision 23) +++ src/syn/prism/PRISM-MetaVars.sdf (working copy) @@ -1,9 +1,10 @@ module PRISM-MetaVars exports variables - [ijkln][0-9]* -> Int {prefer} - [xyzfgh][0-9]* -> Identifier {prefer} - [xyzfgh][0-9]* "'" -> IdentifierPrime {prefer} + [ijkln][0-9]* -> LInt {prefer} + [dr][0-9]* -> LDouble {prefer} + [xyzfgh][0-9]* -> ID {prefer} +%% [xyzfgh][0-9]* "'" -> IdentifierPrime {prefer} [e][0-9]* -> Expression {prefer} "a"[0-9]* "*" -> {Identifier ","}+ {prefer} [m][0-9]* -> Module {prefer} Index: src/syn/prism/PRISM-Identifier.sdf --- src/syn/prism/PRISM-Identifier.sdf (revision 23) +++ src/syn/prism/PRISM-Identifier.sdf (working copy) @@ -31,7 +31,9 @@ Keyword -> ID {reject} lexical restrictions - Identifier -/- [A-Za-z0-9\_] + ID -/- [A-Za-z0-9\_] + + context-free restrictions IdentifierPrime -/- [A-Za-z0-9\_]%% "'" %% FIXME ^^^ %% causes an error oO Index: src/syn/prism/Makefile.am --- src/syn/prism/Makefile.am (revision 23) +++ src/syn/prism/Makefile.am (working copy) @@ -5,7 +5,7 @@ ## Mail <sigoure.benoit@lrde.epita.fr> ## ## Started on Thu Apr 27 17:40:41 2006 SIGOURE Benoit -## Last update Fri May 12 16:52:04 2006 SIGOURE Benoit +## Last update Thu May 18 16:52:52 2006 SIGOURE Benoit ## include $(top_srcdir)/config/Transformers.mk @@ -26,7 +26,8 @@ PRISM.str \ PRISM-StartSymbols.tbl \ PRISM-Prefixed.def \ - StrategoPRISM.def + StrategoPRISM.def \ + StrategoPRISM.tbl pkgdata_DATA = $(pkgdata_DATA_built) sdfdata_DATA = $(pkgdata_DATA_built)