calc_rational

CLI calculator for rational numbers.
git clone https://git.philomathiclife.com/repos/calc_rational
Log | Files | Refs | README

lang.tex (6423B)


      1 \documentclass{article}
      2 \usepackage{amsfonts, amsmath, parskip}
      3 \pagestyle{empty}
      4 \begin{document}
      5 We will define the language, \(L\), of our rational number calculator program.
      6 
      7 Define the set of non-terminal symbols to be
      8 \begin{align*}
      9 N = \{&prog, expr, empty, quit, eval, store, add, mult, neg, exp,\\
     10 &fact,term, rnd, r, abs, recall, par, dec, int, ws, digit, prev, l\}.
     11 \end{align*}
     12 Define the set of terminal symbols to be
     13 \begin{align*}
     14 \Sigma = \{&0,1,2,3,4,5,6,7,8,9,.,+,-,*,/,\string^,!,mod,|(,),round,,,@,s,\\
     15 &space,rand, tab,lf,cr,q\}.
     16 \end{align*}
     17 Define the production rules, \(P\), as the following:
     18 \begin{enumerate}
     19 	\item \(prog \rightarrow expr\ |\ expr\ l\ |\ expr\ l\ prog\)
     20 	\item \(expr \rightarrow empty\ |\ quit\ |\ eval\ |\ store\)
     21 	\item \(empty \rightarrow ws\)
     22 	\item \(quit \rightarrow ws\ q\ ws\)
     23 	\item \(eval\rightarrow ws\ add\ ws\)
     24 	\item \(store\rightarrow ws\ s\ ws\)
     25 	\item \(add \rightarrow add\ ws\ +\ ws\ mult\ |\ add\ ws\ -\ ws\ mult\ |\ mult\)
     26 	\item \(mult \rightarrow mult\ ws\ *\ ws\ neg\ |\ mult\ ws\ /\ ws\ neg\ |\ mult\ ws\ mod\ ws\ neg\ |\ neg\)
     27 	\item \(neg \rightarrow -\ ws\ neg\ |\ exp\)
     28 	\item \(exp \rightarrow fact\ ws\ \string^\ ws\ neg\ |\ fact\)
     29 	\item \(fact \rightarrow fact!\ |\ term\)
     30 	\item \(term \rightarrow dec\ |\ par\ |\ recall\ |\ abs\ |\ r\ |\ rnd\)
     31 	\item \(rnd \rightarrow rand(ws)\ |\ rand(ws\ add\ ws,ws\ add\ ws)\)
     32 	\item \(r \rightarrow round(ws\ add\ ws,ws\ digit\ ws)\)
     33 	\item \(abs \rightarrow |ws\ add\ ws|\)
     34 	\item \(recall \rightarrow @\ |\ @prev\)
     35 	\item \(par \rightarrow (ws\ add \ ws)\)
     36 	\item \(dec \rightarrow int\ |\ int.int\)
     37 	\item \(int \rightarrow digit\ |\ digit\ int\)
     38 	\item \(ws \rightarrow space\ ws\ |\ tab\ ws\ |\ \epsilon\)
     39 	\item \(digit \rightarrow prev\ |\ 0\ |\ 9\)
     40 	\item \(prev \rightarrow 1\ |\ 2\ |\ 3\ |\ 4\ |\ 5\ |\ 6\ |\ 7\ |\ 8\)
     41 	\item \(l \rightarrow lf\ |\ cr\ lf\)
     42 \end{enumerate}
     43 Note that the use of spaces above is purely for visualization purposes (e.g., \(digit\ int\)
     44 does not actually have a space). Define the start symbol to be \(prog\). Define the unambiguous,
     45 context-free grammar to be
     46 \[ G = (N, \Sigma, P, prog). \]
     47 Let \(\mathcal{L}(G)\) be the language generated from \(G\). When \(@\) is not immediately followed by a \(prev\),
     48 let it mean \(@1\). \(@prev\) represents the \(prev^{th}\) most-recent result that has been stored from a \(store\)
     49 expression. \(lf\) is the Unicode scalar value U+000A, \(cr\) is the Unicode scalar value U+000D, \(space\) is the
     50 Unicode scalar value U+0020, \(tab\) is the Unicode scalar value U+0009, and \(\epsilon\) is the empty string. We
     51 define \(\mathbb{Q} \subset L \subset \mathcal{L}(G)\) with \(\mathbb{Q}\) representing the field of rational
     52 numbers such that \(L\) extends \(\mathbb{Q}\) with the ability to recall the previous one to eight \(store\)
     53 results as well as adds the unary operators \(||\), \(-\), and \(!\) as well as the binary operators \(\string^\)
     54 and \(mod\) to mean absolute value, negation, factorial, exponentiation, and modulo respectively.
     55 
     56 Note that this means for \(mult / exp\), \(exp\) does not evaluate to 0. Similarly, \(term\string^exp\) is valid iff
     57 \(term\) evaluates to 1, \(term\) evaluates to 0 and \(exp\) evaluates to a non-negative rational number—\(0^{0}\) is
     58 defined to be 1—or \(term\) evaluates to any other rational number and \(exp\) evaluates to an integer or \(\pm1/2\).
     59 In the event that \(exp\) is \(\pm1/2\), then \(term\) must be the square of a rational number.
     60 \(!\) is only defined for non-negative integers. \(@prev\) is only defined iff at least \(prev\) number of previous
     61 \(store\) expressions have been evaluated.
     62 
     63 \(mod\) is defined iff the left operand evaluates to an integer and the right operand evaluates to a non-zero
     64 integer. This operator returns the minimum non-negative integer, \(r\), that satisfies the equation
     65 \[ n\ mod\ m = r = n - q*m \]
     66 for \(n,q\in\mathbb{Z}\), \(m\in\mathbb{Z}\backslash\{0\}\), and \(r\in\mathbb{N}\).
     67 
     68 It also adds the function \(round\) which rounds the passed expression to \(digit\)-number of fractional digits.
     69 The function \(rand\) when passed no arguments generates a random 64-bit integer. When the function is passed two
     70 arguments, it generates a random 64-bit integer inclusively between the two arguments. In the latter case, the
     71 second argument must evaluate to a number greater than or equal to the first; and there must be at least one 64-bit
     72 integer in that interval.
     73 
     74 From the above grammar, we see the expression precedence in descending order is the following:
     75 \begin{enumerate}
     76 	\item number literals, \(()\), \(@\), \(||\), \(round()\), \(rand()\)
     77 	\item \(!\)
     78 	\item \(\string^\)
     79 	\item \(-\) (the unary negation operator)
     80 	\item \(*\), \(/\), \(mod\)
     81 	\item \(+\), \(-\)
     82 \end{enumerate}
     83 with \(\string^\) being right-associative and the rest of the binary operators being left-associative.
     84 Last, for \(j \in \mathbb{N}\) and \(d_{j} \in \{0,1,2,3,4,5,6,7,8,9\}\subset \mathbb{Z}\), we have
     85 \begin{align*}
     86 d_{0}d_{1}\cdots d_{n}.d_{n+1}\cdots d_{n+i} = (&d_{0}*10^{n} + d_{1}*10^{n-1} +\cdots + d_{n}*10^{0}\\
     87 													   &+d_{n+1}*10^{-1} +\cdots + d_{n+i}*10^{-i})
     88 \end{align*}
     89 where for \(k\in\mathbb{N}\)
     90 \[ 10^{k} = \overbrace{10 * 10 *\cdots *10}^{k} \]
     91 and for \(l\in\mathbb{Z}^{-}\)
     92 \[ 10^{l} = \overbrace{1/10 * 1/10 *\cdots *1/10}^{|l|}. \]
     93 As a consequence of above, we have the following example:
     94 \[ 1/1.5 = 1/(3/2) = 2/3 \neq 1/6 = 1/3/2. \]
     95 For \(n\in\mathbb{N}\) we define the factorial operator as
     96 \[ n! = n * (n - 1) *\cdots * 1 \]
     97 which of course equals 1 when \(n = 0\).
     98 
     99 The \(empty\) expression (i.e., expression consisting of spaces and tabs) returns the result of the previous \(eval\)
    100 expression in decimal form—in the event there is no such previous expression, it returns the empty string. The
    101 minimum number of digits will be used; if the value requires an infinite number of digits, then the value will be
    102 rounded to 9 fractional digits. The \(quit\) expression (i.e., expression consisting of spaces, tabs, and exactly
    103 one \(q\)) causes the program to terminate. The \(store\) expression (i.e., expression consisting of spaces, tabs,
    104 and exactly one \(s\)) stores and returns the result from the previous \(eval\) expression and can be recalled with
    105 \(@\). At most 8 results can be stored; after which the oldest result is overwritten. Stored results cannot be
    106 unstored.
    107 \end{document}