Compiler/lexical analyzer: Difference between revisions

Content added Content deleted
m (minor edits)
m (Fix a bug in make-this-or-that-handler and use lisp keywords instead of obscure symbols.)
Line 1,677:
do (setf may-end (char= ch #\*))
finally (return (read stream t nil t))))
(t (make-token :name '|Op_divide|:op-divide :line (line-of stream) :column (column-of stream)))))
 
(defun make-constant-handler (token-name)
Line 1,693:
(read-char stream nil nil t)
(make-token :name then :line line :column column))
((make-token :name else :line line :column column))
(t (lexermake-errortoken :name else "Unrecognized:line characterline '~A'":column next))))column))
(t
(lexer-error "Unrecognized character '~A'" next))))))
 
(defun identifier? (symbol)
Line 1,709 ⟶ 1,711:
(defun id->keyword (id line column)
(case id
(|if| (make-token :name '|Keyword_if|:keyword-if :line line :column column))
(|else| (make-token :name '|Keyword_else|:keyword-else :line line :column column))
(|while| (make-token :name '|Keyword_while|:keyword-while :line line :column column))
(|print| (make-token :name '|Keyword_print|:keyword-print :line line :column column))
(|putc| (make-token :name '|Keyword_putc|:keyword-putc :line line :column column))
(t nil)))
 
Line 1,725 ⟶ 1,727:
(if (identifier? obj)
(or (id->keyword obj line column)
(make-token :name '|Identifier|:identifier :value obj :line line :column column))
(lexer-error "Invalid identifier name: ~A" obj))))))
 
Line 1,736 ⟶ 1,738:
(let ((obj (read stream t nil t)))
(if (integerp obj)
(make-token :name '|Integer|:integer :value obj :line line :column column)
(lexer-error "Invalid integer: ~A" obj))))))
 
Line 1,754 ⟶ 1,756:
(t ch))))
(if (char= #\' (read-char stream t nil t))
(make-token :name '|Integer|:integer :value (char-code parsed) :line line :column column)
(lexer-error "Only one character is allowed in character literal"))))
 
Line 1,773 ⟶ 1,775:
(t ch)))
(vector-push-extend ch result)
finally (return (make-token :name '|String|:string :value result :line line :column column))))
 
(defun make-lexer-readtable ()
Line 1,783 ⟶ 1,785:
 
;; operators
(set-macro-character #\* (make-constant-handler '|Op_multiply|:op-multiply))
(set-macro-character #\/ #'handle-divide-or-comment)
(set-macro-character #\% (make-constant-handler '|Op_mod|:op-mod))
(set-macro-character #\+ (make-constant-handler '|Op_add|:op-add))
(set-macro-character #\- (make-constant-handler '|Op_subtract|:op-subtract))
(set-macro-character #\< (make-this-or-that-handler #\= '|Op_lessequal|:op-lessequal '|Op_less|:op-less))
(set-macro-character #\> (make-this-or-that-handler #\= '|Op_greaterequal|:op-greaterequal '|Op_greater|:op-greater))
(set-macro-character #\= (make-this-or-that-handler #\= '|Op_equal|:op-equal '|Op_assign|:op-assign))
(set-macro-character #\! (make-this-or-that-handler #\= '|Op_notequal|:op-notequal '|Op_not|:op-not))
(set-macro-character #\& (make-this-or-that-handler #\& '|Op_and|:op-and))
(set-macro-character #\| (make-this-or-that-handler #\| '|Op_or|:op-or))
 
;; symbols
(set-macro-character #\( (make-constant-handler '|LeftParen|:leftparen))
(set-macro-character #\) (make-constant-handler '|RightParen|:rightparen))
(set-macro-character #\{ (make-constant-handler '|LeftBrace|:leftbrace))
(set-macro-character #\} (make-constant-handler '|RightBrace|:rightbrace))
(set-macro-character #\; (make-constant-handler '|Semicolon|:semicolon))
(set-macro-character #\, (make-constant-handler '|Comma|:comma))
 
;; identifiers & keywords
Line 1,830 ⟶ 1,832:
(token-line token) (token-column token) (token-name token) (token-value token))
finally (format t "~5D ~5D ~15A~%"
(line-of stream) (column-of stream) '|End_of_input|:end-of-input)
(close stream))))
 
Line 1,845 ⟶ 1,847:
(if file
(lex file)
(error "File must be specified"))))</lang>
</lang>
{{out|case=test case 3}}
<pre> 5 16 Keyword_printKEYWORD-PRINT
5 40 Op_subtractOP-SUBTRACT
6 16 Keyword_putcKEYWORD-PUTC
6 40 Op_lessOP-LESS
7 16 Keyword_ifKEYWORD-IF
7 40 Op_greaterOP-GREATER
8 16 Keyword_elseKEYWORD-ELSE
8 40 Op_lessequalOP-LESSEQUAL
9 16 Keyword_whileKEYWORD-WHILE
9 40 Op_greaterequalOP-GREATEREQUAL
10 16 LeftBraceLEFTBRACE
10 40 Op_equalOP-EQUAL
11 16 RightBraceRIGHTBRACE
11 40 Op_notequalOP-NOTEQUAL
12 16 LeftParenLEFTPAREN
12 40 Op_andOP-AND
13 16 RightParenRIGHTPAREN
13 40 Op_orOP-OR
14 16 Op_subtractOP-SUBTRACT
14 40 SemicolonSEMICOLON
15 16 Op_notOP-NOT
15 40 CommaCOMMA
16 16 Op_multiplyOP-MULTIPLY
16 40 Op_assignOP-ASSIGN
17 16 Op_divideOP-DIVIDE
17 40 IntegerINTEGER 42
18 16 Op_modOP-MOD
18 40 StringSTRING "String literal"
19 16 Op_addOP-ADD
19 40 IdentifierIDENTIFIER variable_name
20 26 IntegerINTEGER 10
21 26 IntegerINTEGER 92
22 26 IntegerINTEGER 32
23 1 End_of_inputEND-OF-INPUT </pre>
 
=={{header|Euphoria}}==