You have already implemented a lexical analyzer in Assignment #1 and a parser to recognize
grammatical rules in Assignment #2. In this assignment, you will be adding semantics to the
design of a small programming language to help implement blockchain. The goal of blockchain
is to allow digital information to be recorded and distributed, but not edited. In this way, a
blockchain is a foundation for immutable records of transactions that cannot be altered, deleted,
or destroyed. The semantics that you must implement in this assignment is as follows: 1. Each
time a new blockchain is created, you must extract attributes and verifies if each attribute has a
valid type. Returns false if at least one is invalid or returns true otherwise. 2. When the add
operator (keyword) is used, the data must be stored in a dictionary. 3. When errors are detected,
the parser must describe the error, including the line of the code where it occurs. 4. When
arithmetic expressions are used, the parser will implement the corresponding arithmetic
operations. For simplicity purposes, the blockchain only will store arithmetic expressions and
strings.
import ply.lex as lex
import ply.yacc as yacc
tokens = (
'ID',
'BLOCK',
'VAR',
'ADD',
'PRINT',
'VIEW',
'RUN',
'MINE',
'EXPORT',
'STRING',
'INT',
'LONG',
'FLOAT',
'LIST',
'TUPLE',
'DICT',
'NUMBER',
'ASSIGN',
'TYPEASSIGN',
'SEPARATOR',
'LPAREN',
'RPAREN',
'NE',
'LT',
'GT',
'LE',
'GE',
'PLUS',
'MINUS',
'STAR',
'SLASH',
'PCT',
'COMMENT',
'WHITESPACE'
)
t_ASSIGN = r'='
t_TYPEASSIGN = r':'
t_SEPARATOR = r','
t_LPAREN = r'('
t_RPAREN = r')'
t_NE = r'!='
t_LT = r'<'
t_GT = r'>'
t_LE = r'<='
t_GE = r'>='
t_PLUS = r'+'
t_MINUS = r'-'
t_STAR = r'*'
t_SLASH = r'/'
t_PCT = r'%'
t_ignore_COMMENT = r'#.'
t_ignore_WHITESPACE = r's+'
keywords = {
'BLOCK': 'KEYWORD',
'VAR': 'KEYWORD',
'ADD': 'KEYWORD',
'PRINT': 'KEYWORD',
'VIEW': 'KEYWORD',
'RUN': 'KEYWORD',
'MINE': 'KEYWORD',
'EXPORT': 'KEYWORD',
'STR':'KEYWORD',
'INT': 'KEYWORD',
'LONG': 'KEYWORD',
'FLOAT': 'KEYWORD',
'LIST': 'KEYWORD',
'TUPLE': 'KEYWORD',
'DICT':'KEYWORD',
}
tokens1 = ['ID',
'BLOCK','VAR','ADD','PRINT','VIEW','RUN','MINE','EXPORT','STRING','LONG','FLOAT','L
IST','TUPLE','DICT','NUMBER','ASSIGN','TYPEASSIGN','SEPARATOR','LPAREN','RPARE
N','NE','LT','GT','LE','GE','PLUS','MINUS','STAR','SLASH', 'PCT',
'COMMENT','WHITESPACE']
+ list(keywords.values())
# dictionary to store values
values = {}
def t_KEYWORD(t):
r'DEF | VAR | INT | IF | ELSE'
t.type = keywords.get(t.value, 'KEYWORD')
return t
def t_ID(t):
r'[a-zA-Z_][a-zA-Z_0-9]*'
t.type = keywords.get(t.value, 'ID')
return t
def t_NUM(t):
r'[0-9]+'
t.type = keywords.get(t.value, 'INT')
return t
def t_COMMENT(t):
r'//.'
t.type = keywords.get(t.value, 'COMMENT')
pass
def t_newline(t):
r'n+'
t.lexer.lineno += len(t.value)
def t_error(t):
print("Illegal character '%s'" % t.value[0])
t.lexer.skip(1)
def p_block(p):
"""
block : BLOCK ID ASSIGN LPAREN attributes RPAREN
| ADD ID ASSIGN LPAREN new_atts RPAREN
| PRINT ID
| RUN ID
| MINE ID
| EXPORT ID
| VIEW ID
"""
pass
def p_type(p):
"""
type : STRING
| INT
| LONG
| FLOAT
| LIST
| TUPLE
| DICT
"""
pass
def p_attribute(p):
"""
attribute : ID TYPEASSIGN type
"""
pass
def p_attributes(p):
"""
attributes : attribute
| attributes SEPARATOR attribute
"""
pass
def p_new_att(p):
"""
new_att : ID TYPEASSIGN STRING
| ID TYPEASSIGN NUMBER
"""
pass
def p_new_atts(p):
"""
new_atts : new_att
| new_atts SEPARATOR new_att
"""
pass
def p_expr(p):
"""
expr : term
| expr PLUS term
| expr MINUS term
"""
pass
def p_term(p):
"""
term : factor
| term STAR factor
| term SLASH factor
| term PCT factor
"""
pass
def p_factor(p):
"""
factor : ID
| NUMBER
| LPAREN expr RPAREN
| factor LPAREN argsopt RPAREN
"""
pass
def p_test(p):
"""
test : expr NE expr
| expr LT expr
| expr LE expr
| expr GE expr
| expr GT expr
"""
pass
def p_argsopt(p):
"""
argsopt : args
|
"""
pass
def p_args(p):
"""
args : expr SEPARATOR args
| expr
"""
pass
def p_error(p):
print("Syntax error at token", p, "line:", p.lexer.lineno)
textfile = open("TestFile.txt","r")
data = textfile.read()
parser = yacc.yacc()
lexer = lex.lex()
lexer.input(data)
while True:
try:
s = input(data)
except EOFError:
break
if not s: continue
result = parser.parse(s)
print(result)

You have already implemented a lexical analyzer in Assignment #1 and.pdf

  • 1.
    You have alreadyimplemented a lexical analyzer in Assignment #1 and a parser to recognize grammatical rules in Assignment #2. In this assignment, you will be adding semantics to the design of a small programming language to help implement blockchain. The goal of blockchain is to allow digital information to be recorded and distributed, but not edited. In this way, a blockchain is a foundation for immutable records of transactions that cannot be altered, deleted, or destroyed. The semantics that you must implement in this assignment is as follows: 1. Each time a new blockchain is created, you must extract attributes and verifies if each attribute has a valid type. Returns false if at least one is invalid or returns true otherwise. 2. When the add operator (keyword) is used, the data must be stored in a dictionary. 3. When errors are detected, the parser must describe the error, including the line of the code where it occurs. 4. When arithmetic expressions are used, the parser will implement the corresponding arithmetic operations. For simplicity purposes, the blockchain only will store arithmetic expressions and strings. import ply.lex as lex import ply.yacc as yacc tokens = ( 'ID', 'BLOCK', 'VAR', 'ADD', 'PRINT', 'VIEW', 'RUN', 'MINE', 'EXPORT', 'STRING', 'INT', 'LONG', 'FLOAT', 'LIST', 'TUPLE', 'DICT', 'NUMBER',
  • 2.
    'ASSIGN', 'TYPEASSIGN', 'SEPARATOR', 'LPAREN', 'RPAREN', 'NE', 'LT', 'GT', 'LE', 'GE', 'PLUS', 'MINUS', 'STAR', 'SLASH', 'PCT', 'COMMENT', 'WHITESPACE' ) t_ASSIGN = r'=' t_TYPEASSIGN= r':' t_SEPARATOR = r',' t_LPAREN = r'(' t_RPAREN = r')' t_NE = r'!=' t_LT = r'<' t_GT = r'>' t_LE = r'<=' t_GE = r'>=' t_PLUS = r'+' t_MINUS = r'-' t_STAR = r'*' t_SLASH = r'/' t_PCT = r'%' t_ignore_COMMENT = r'#.'
  • 3.
    t_ignore_WHITESPACE = r's+' keywords= { 'BLOCK': 'KEYWORD', 'VAR': 'KEYWORD', 'ADD': 'KEYWORD', 'PRINT': 'KEYWORD', 'VIEW': 'KEYWORD', 'RUN': 'KEYWORD', 'MINE': 'KEYWORD', 'EXPORT': 'KEYWORD', 'STR':'KEYWORD', 'INT': 'KEYWORD', 'LONG': 'KEYWORD', 'FLOAT': 'KEYWORD', 'LIST': 'KEYWORD', 'TUPLE': 'KEYWORD', 'DICT':'KEYWORD', } tokens1 = ['ID', 'BLOCK','VAR','ADD','PRINT','VIEW','RUN','MINE','EXPORT','STRING','LONG','FLOAT','L IST','TUPLE','DICT','NUMBER','ASSIGN','TYPEASSIGN','SEPARATOR','LPAREN','RPARE N','NE','LT','GT','LE','GE','PLUS','MINUS','STAR','SLASH', 'PCT', 'COMMENT','WHITESPACE'] + list(keywords.values()) # dictionary to store values values = {} def t_KEYWORD(t): r'DEF | VAR | INT | IF | ELSE' t.type = keywords.get(t.value, 'KEYWORD') return t
  • 4.
    def t_ID(t): r'[a-zA-Z_][a-zA-Z_0-9]*' t.type =keywords.get(t.value, 'ID') return t def t_NUM(t): r'[0-9]+' t.type = keywords.get(t.value, 'INT') return t def t_COMMENT(t): r'//.' t.type = keywords.get(t.value, 'COMMENT') pass def t_newline(t): r'n+' t.lexer.lineno += len(t.value) def t_error(t): print("Illegal character '%s'" % t.value[0]) t.lexer.skip(1) def p_block(p): """ block : BLOCK ID ASSIGN LPAREN attributes RPAREN | ADD ID ASSIGN LPAREN new_atts RPAREN | PRINT ID | RUN ID | MINE ID | EXPORT ID | VIEW ID """ pass
  • 5.
    def p_type(p): """ type :STRING | INT | LONG | FLOAT | LIST | TUPLE | DICT """ pass def p_attribute(p): """ attribute : ID TYPEASSIGN type """ pass def p_attributes(p): """ attributes : attribute | attributes SEPARATOR attribute """ pass def p_new_att(p): """ new_att : ID TYPEASSIGN STRING | ID TYPEASSIGN NUMBER """ pass
  • 6.
    def p_new_atts(p): """ new_atts :new_att | new_atts SEPARATOR new_att """ pass def p_expr(p): """ expr : term | expr PLUS term | expr MINUS term """ pass def p_term(p): """ term : factor | term STAR factor | term SLASH factor | term PCT factor """ pass def p_factor(p): """ factor : ID | NUMBER | LPAREN expr RPAREN | factor LPAREN argsopt RPAREN """ pass
  • 7.
    def p_test(p): """ test :expr NE expr | expr LT expr | expr LE expr | expr GE expr | expr GT expr """ pass def p_argsopt(p): """ argsopt : args | """ pass def p_args(p): """ args : expr SEPARATOR args | expr """ pass def p_error(p): print("Syntax error at token", p, "line:", p.lexer.lineno) textfile = open("TestFile.txt","r") data = textfile.read() parser = yacc.yacc()
  • 8.
    lexer = lex.lex() lexer.input(data) whileTrue: try: s = input(data) except EOFError: break if not s: continue result = parser.parse(s) print(result)