Question

In: Computer Science

Using the descriptions below, write a scanner for numbers, symbols, comments, arithmetic operators, and parenthesis in...

Using the descriptions below, write a scanner for numbers, symbols, comments, arithmetic operators, and parenthesis in Racket or scheme.

- a number is

one or more digits |

zero of more digits followed by a decimal point followed by one or more digits |

one or more digits followed by a decimal point followed by zero or more digits



- a symbol is
     one or more characters from the set [_A-Za-z] followed by zero or more characters from the set [_A-Za-z0-9]

- a comment is
     the literal string "#" followed by zero or more characters until the end of the line


- an arithmetic operator is
     + |
     - |
     * |
     /

- a parenthesis is
     ( |
     )


Your scanner must convert input text into the following tokens: NUM, SYM, ADD, SUBTRACT, MULTIPLY, DIVIDE, LPAREN, RPAREN, ERROR. Turn in your scanner implementations and test cases. Your test cases should show that your scanner produces a correct list of tokens when given valid input and the scanner output should contain an ERROR token when given invalid input. the output must all be list containing each output token.

Sample Racket return value from scanner: (NUM NUM NUM ADD NUM MULTIPLY NUM ADD NUM EOF) or (NUM NUM NUM ERROR NUM MULTIPLY NUM ADD NUM EOF)

For Racket, you may use the parser-tools/lex library that comes with Racket.

Solutions

Expert Solution

lang racket
;;; IMPORT
;; Import the lexer tools 
(require parser-tools/yacc
         parser-tools/lex
         (prefix-in : parser-tools/lex-sre)  ; names from lex-sre are prefixed with :
         ;                                     to avoid name collisions
         syntax/readerr)

;;; REGULAR EXPRESSIONS

;; Names for regular expressions matching letters and digits.
;; Note that :or are prefixed with a : due to (prefix-in : ...) above
(define-lex-abbrevs
  [letter     (:or (:/ "a" "z") (:/ #\A #\Z) )]
  [digit      (:/ #\0 #\9)])

;;; TOKENS

;; Tokens such as numbers (and identifiers and strings) carry a value
;; In the example only the NUMBER token is used, but you may need more.
(define-tokens value-tokens (NUMBER IDENTIFIER STRING))

;; Tokens that don't carry a value.
(define-empty-tokens op-tokens (newline :=  = < > + - * / ^  EOF))

;;; LEXER

;; Here the lexer (aka the scanner) is defined.
;; The construct lexer-src-pos evaluates to a function which scans an input port
;; returning one position-token at a time.

;; A position token contains besides the actual token also source location information
;; (i.e. you can see where in the file the token was read)

(define lex
  (lexer-src-pos
   [(eof)                                            ; input: eof of file     
    'EOF]                                            ; output: the symbol EOF

   [(:or #\tab #\space #\newline)                    ; input: whitespace
    (return-without-pos (lex input-port))]           ; output: the next token
   ;                                                           (i.e. skip the whitespace)

   [#\newline                                        ; input: newline
    (token-newline)]                                 ; ouput: a newline-token   
   ;                                                 ; note:  (token-newline) returns 'newline

   [(:or ":=" "+" "-" "*" "/" "^" "<" ">" "=")       ; input:  an operator
    (string->symbol lexeme)]                         ; output: corresponding symbol

   [(:+ digit)                                       ; input:  digits
    (token-NUMBER (string->number lexeme))]))        ; outout: a NUMBER token whose value is
;                                                    ;         the number
;                                                    ; note:   (token-value token)
;                                                              returns the number

;;; TEST

(define input (open-input-string "123+456"))

(lex input) ; (position-token (token 'NUMBER 123) (position 1 #f #f) (position 4 #f #f))
(lex input) ; (position-token '+ (position 4 #f #f) (position 5 #f #f))
(lex input) ; (position-token (token 'NUMBER 456) (position 5 #f #f) (position 8 #f #f))
(lex input) ; (position-token 'EOF (position 8 #f #f) (position 8 #f #f))


;; Let's make it a little easier to play with the lexer.

(define (string->tokens s)
  (port->tokens (open-input-string s)))

(define (port->tokens in)
  (define token (lex in))
  (if (eq? (position-token-token token) 'EOF)
      '()
      (cons token (port->tokens in))))

(map position-token-token (string->tokens "123*45/3"))   ; strip positions
; Output:

; (list (token 'NUMBER 123)
;        '*
;        (token 'NUMBER 45)
;        '/
;        (token 'NUMBER 3))

Related Solutions

USING C++: Consider the precedence levels of the relational, logical, and arithmetic operators of the PySub...
USING C++: Consider the precedence levels of the relational, logical, and arithmetic operators of the PySub language to be as follows (NOTE: 5 has highest precedence and 0 lowest): 5 *, /, % 4 +, - 3 <, <=, >, >=, !=, == 2 not 1 and 0 or 1.  Infix-Postfix Conversion and Evaluation with Logical and Relational operators – Convert the following infix expression to a postfix expression and evaluate the result (assume that true=1 and false=0). Provide both the...
using python without external libaries Using integer arithmetic operators '+' and '-', print all combinations that...
using python without external libaries Using integer arithmetic operators '+' and '-', print all combinations that sum up to 'sum' by inserting the operators between digits in 'number'. example for 'number=123456789' and 'sum = 0' Print the output using the terminal: Output should be exactly like this from 1 - 22 1 : +1+2-34-56+78+9=0 2 : +1-2-34+5+6+7+8+9=0 3 : +1-23-4-56-7+89=0 ... 12 : -1+2+34-5-6-7-8-9=0 13 : -1+23+4+56+7-89=0 14 : -1-2+34+56-78-9=0 ... 22 : -12-34+56+7-8-9=0
Using Python write the following script as well as using comments By considering the details below,...
Using Python write the following script as well as using comments By considering the details below, write a class that will work out the body mass index for specific values of weight and height. The design of the actual class is shown below: bmi -weight:float -height:float -bmi:float +set_weight(weight:float) +set_height(height:float) +calc_bmi() +get_bmi():float specific designs of the methods are shown below: set_weight set the weight attribute to the value in the parameter weight set_height set the height attribute to the value in...
Write a balanced chemical equation for each of the following descriptions of chemical reactions, including state symbols:
Write a balanced chemical equation for each of the following descriptions of chemical reactions, including state symbols:a. Aluminum metal reacts with aqueous iron(II) chloride to form aqueous aluminum chloride and iron metal.b. Solid cobalt (III) oxide reacts with solid carbon to produce solid cobalt and carbon dioxide gas.c. Nitrogen dioxide gas reacts with gaseous oxygen and liquid water to form aqueous nitric acid.
Write a c++ program to load two column of numbers, do arithmetic operations to the data...
Write a c++ program to load two column of numbers, do arithmetic operations to the data points by following the steps below carefully. Also we need to capture the running time in microseconds for each of these and also the time taken for basic operation. Steps to complete. 0. Download the data file named Datafile1.data from the file area of the assignment. 1. Load two columns of data points, each column into a storage area, preferably a vector. 2. Initialize/start...
Write a program to validate parenthesis of any given equation by using the following criteria (you...
Write a program to validate parenthesis of any given equation by using the following criteria (you MUST use stacks); Number of open parenthesis “(“must be same as number of close parentheses “)” For example if I input “3 + 4 * (98+34*(34+8)*34*(3+x)” the program should display an error message, because number of open parenthesis “(“is 3 and number of closed “)” parenthesis is 2. Stack-Driver.cpp: #include "stack.h" #include "stack.cpp" #include<stdio.h> #include<stdlib.h> #include<time.h> int main() {    stack<int> my_stack(100);    srand(time(NULL));...
Based on the descriptions given below, write the JavaScript codes to calculate the amount to be...
Based on the descriptions given below, write the JavaScript codes to calculate the amount to be paid for books purchased.  Declare all the variables used in this program.  Ask the user to key-in the book code using a prompt() method. Store the value in a variable named book_code.  Ask the user to key-in the number of books purchased using a prompt() method. Store the value in a variable named book_qty.  Ask the user whether they have...
Write a program using a Scanner that asks the user for a number n between 1...
Write a program using a Scanner that asks the user for a number n between 1 and 9 (inclusive). The program prints a triangle with 2n - 1 rows. The first row contains only the square of 1, and it is right-justified. The second row contains the square of 2 followed by the square of 1, and is right justified. Subsequent rows include the squares of 3, 2, and 1, and then 4, 3, 2 and 1, and so forth...
The Hypothesis Test for One Mean 5) Using the proper symbols, write the null and alternative...
The Hypothesis Test for One Mean 5) Using the proper symbols, write the null and alternative hypotheses for each scenario below. (2 points each) a) In 1920, the average age men got married for the first time was 24.6 years. It is believed that young people are waiting longer to get married. A recent study of 120 men found that the average age the men got married for the first time was 29.5 years with a standard deviation of 5.2...
Using the below two SQL queries and comments below, provide explanation on why the output count...
Using the below two SQL queries and comments below, provide explanation on why the output count varies and which SQL yield correct result. (20 points) Both SQLs are joining two tables Both SQLs are syntactically correct Query #1 returns about 19614 rows versus Query #2 returns 3550134. Query #1: select * from person.Address addr inner join person.StateProvince prov on addr.StateProvinceID = prov.StateProvinceID Query #2: select * from person.Address addr,person.StateProvince prov
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT