Last active
May 12, 2017 00:32
-
-
Save zed/e7bad76d922825604d1d93bb43f6cfa6 to your computer and use it in GitHub Desktop.
Revisions
-
zed revised this gist
May 12, 2017 . 1 changed file with 53 additions and 26 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,10 +1,11 @@ /** Convert Roman numerals given on the command line to decimals. $ ragel -F0 -o roman_numerals.c roman_numerals.rl $ gcc -finput-charset=utf-8 -fexec-charset=utf-8 -o roman_numerals roman_numerals.c $ ./roman_numerals IX Ⅻ CCCC 9 12 400 $ ./roman_numerals IIX && exit 1 || echo invalid invalid */ @@ -17,43 +18,69 @@ write data; }%% int from_roman_to_int(const char* s) { int n, cs; const char *p = s, *pe = s + strlen(s), *eof = pe; %%{ # units I = ('I' | 'i' | "Ⅰ" | "ⅰ") %{ n += 1; }; II = I I | ("Ⅱ" | "ⅱ") %{ n += 2; }; III = I I I | ("Ⅲ" | "ⅲ") %{ n += 3; }; V = ('V' | 'v' | "Ⅴ" | "ⅴ") %{ n += 5; }; VI = V I | ("Ⅵ" | "ⅵ") %{ n += 6; }; VII = V I I | ("Ⅶ" | "ⅶ") %{ n += 7; }; VIII = V I I I | ("Ⅷ" | "ⅷ") %{ n += 8; }; # tens X = ('X' | 'x' | "Ⅹ" | "ⅹ") %{ n += 10; }; XI = ("Ⅺ" | "ⅺ") %{ n += 11; }; XII = ("Ⅻ" | "ⅻ") %{ n += 12; }; L = ('L' | 'l' | "Ⅼ" | "ⅼ") %{ n += 50; }; # hundreds C = ('C' | 'c' | "Ⅽ" | "ⅽ") %{ n += 100; }; D = ('D' | 'd' | "Ⅾ" | "ⅾ") %{ n += 500; }; # thousands M = ('M' | 'm' | "Ⅿ" | "ⅿ") %{ n += 1000;}; # subtractive principle IV = I V %{ n -= 2; } | I{4} | ("Ⅳ" | "ⅳ") %{ n += 4; }; IX = I X %{ n -= 2; } | V I{4} | ("Ⅸ" | "ⅸ") %{ n += 9; }; XL = X L %{ n -= 20; }; XC = X C %{ n -= 20; }; CD = C D %{ n -= 200; }; CM = C M %{ n -= 200; }; thousands = M{,4}; hundreds = CM | CD | D? C{,4}; tens = XC | XL | L? X{,4}; units = IX | VIII | VII | VI | V | IV | III | II | I; numeral = thousands? hundreds? (XII? | XI? | tens? units?); main := numeral > { n = 0; } ; write init; write exec; }%% return (cs == roman_numerals_error || cs == roman_numerals_start) ? -1 : n ; } int main(int argc, char* argv[]) { if (argc < 2) { fputs("Usage: roman_numerals <text>...\n", stderr); exit(EXIT_FAILURE); } for (int i = 1; i < argc; ++i) { int n = from_roman_to_int(argv[i]); if (n < 0) exit(EXIT_FAILURE); printf("%d\n", n); /* print result */ } return 0; } -
zed renamed this gist
May 10, 2017 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
zed created this gist
May 10, 2017 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,59 @@ /** Convert Roman numerals given on the command line to decimals. $ ragel -F0 -p -o roman_numerals.c roman_numerals.rl $ cc -o roman_numerals roman_numerals.c $ ./roman_numerals IX XII 9 12 $ ./roman_numerals IIX && exit 1 || echo invalid invalid */ #include <string.h> #include <stdio.h> #include <stdlib.h> %%{ machine roman_numerals; write data; }%% int main(int argc, char* argv[]) { if (argc < 2) { fputs("Usage: roman_numerals <text>...\n", stderr); exit(EXIT_FAILURE); } for (int i = 1; i < argc; ++i) { int n, cs; char *p = argv[i], *pe = p + strlen(p), *eof = pe; %%{ thousands = ('M' %{ n += 1000; }){,3}; hundreds = "CM" %{ n += 900; } | "CD" %{ n += 400; } | ('D' %{ n += 500; } )? ('C' %{ n += 100; }){,3}; tens = "XC" %{ n += 90; } | "XL" %{ n += 40; } | ('L' %{ n += 50; } )? ('X' %{ n += 10; }){,3}; units = "IX" %{ n += 9; } | "IV" %{ n += 4; } | ('V' %{ n += 5; } )? ('I' %{ n += 1; }){,3}; numeral = thousands hundreds tens units; main := numeral > { n = 0; } ; write init; write exec; }%% if (!n || cs == roman_numerals_error) exit(EXIT_FAILURE); printf("%d\n", n); /* print result */ } return 0; }