To read expressions and statements from a text file and generate ARM assembly instructions that can be run directly on Keil uVision IDE. The assembly instructions are specific to a generic ARM Cotrex M4 device/board.
Expressions from the input source are read. Lexical analysis is performed on the expressions to obtain the appropriate tokens. Thereafter, parsing is done using pre-defined grammar rules to generate the specific assembly instructions. These instructions are written to a .s file and can be simulated/debugged on uVision.
Type | Name |
---|---|
Langauge | Python |
Package | PLY |
Lexer | Lex |
Parser | Yacc |
PLY stands for Python Lex and Yacc. It is a Python version of Lex and Yacc that has the same functionality as Lex and Yacc but has a different interface with ample support for debugging. Simply put, it provides an easy way to write a compiler.
Tokens are defined either using regular expressions or functions in the code for the lexer. The lexer splits up the input file into these tokens.
t_NAME = r’[a-zA-Z_][a-zA-Z0-9_]*’
def t_NUMBER(t):
r’\d+’ t.
value = int(t.value)
return t
Grammar rules are defined within functions. Tokens are imported from the lexer. PLY uses LR parsing aka Shift Reduce parsing. Results propagate up through the grammar in a bottom up fashion.
assign : NAME EQUALS expr
expr :NUMBER
def p_expr(p):
'''expr : expr PLUS expr | expr MINUS expr '''
Assembly instructions specific to ARM Cortex M4 are generated and written to an assembly file
a=8
b=3
c=4
d=2
e=1
g=a+b-c*d/a%e
a>b?f=5:f=3
if a<b then f=5 else g=3
a>>d
c<<e
h=a%b
AREA appcode, CODE, READONLY
EXPORT __main
ENTRY
__main FUNCTION
MOV r0 ,#8
MOV r1 ,#3
MOV r2 ,#4
MOV r3 ,#2
MOV r4 ,#1
ADD r5 ,r0 ,r1
MUL r6, r2, r3
SDIV r7, r6, r0
SDIV r8, r7, r4
MLS r8, r8, r4, r7
SUB r9 ,r5 ,r8
MOV r10 ,#11
CMP r0, r1
MOVGT r11 ,#5
MOVLE r11 ,#3
CMP r0, r1
MOVLT r11 ,#5
MOVGE r10 ,#3
LSR r12, r0, r3
LSL r5, r2, r4
SDIV r6, r0, r1
MLS r6, r6, r1, r0
MOV r7 ,#2
stop B stop
ENDFUNC
END
For testing purpose we are also replicating those r12 registers of arm cortex M4 and maintaining a dictionary of variable, value pairs and dictionary of variable, register pairs for both debugging and reclaiming of registers for further usage if required.
Debug dump for the above test file is as follow.
register dump
{'r12': 2, 'r10': 3, 'r11': 5, 'r4': 1, 'r5': 8, 'r6': 2, 'r7': 2, 'r0': 8, 'r1': 3, 'r2': 4, 'r3': 2, 'r8': 0, 'r9': 0}
dictionary of variable,value pairs
{'a': 8, 'b': 3, 'c': 4, 'd': 2, 'e': 1, 'f': 5, 'g': 3, 'h': 2}
dictionary of variable,register mappings
{'a': 'r0',
'b': 'r1',
'c': 'r2',
'd': 'r3',
'e': 'r4',
'f': 'r11',
'g': 'r10',
'h': 'r7'}
Now this is available as a snap package at here
$ sudo snap install aec-arm
$ aec-arm <input_file.txt>
An output file will be generated with name as autogen.s in the current working directory which can be run on keil simulator on successful execution.
Deepika Raj (https://github.com/depikaraj)
Prashanthi Kadambi (https://github.com/amateurcoder10)
Seelapureddy Venkata Rama Aditya Reddy (https://github.com/SvrAdityaReddy)
[1] Writing Parsers and Compilers with PLY by David Beazley
[2] Python Lex-Yacc
[3] Create your first snap
[4] The python plugin
[5] Python Apps the Right Way: entry points and scripts
[6] Interfaces reference