first
This commit is contained in:
parent
586a58fd94
commit
c707e3253c
53 changed files with 500 additions and 27 deletions
88
ass3/zbirnik/_build/default/lib/parser.ml
Normal file
88
ass3/zbirnik/_build/default/lib/parser.ml
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
(*sprejme .asm file in pretvori v neko interno predstavitev*)
|
||||
|
||||
type line = {
|
||||
line_no : int;
|
||||
label : string option;
|
||||
opcode : string;
|
||||
operand : string list; (*list of operands*)
|
||||
comment : string option;
|
||||
mutable loc : int option; (* assigned in pass1 *)
|
||||
}
|
||||
|
||||
|
||||
let parseLine (lineNo : int) (line : string) : line option=
|
||||
let trimmedLine = String.trim (line) in (*Znebimo se zacetnih in koncnih presledkov*)
|
||||
(*empty line or comment line*)
|
||||
if trimmedLine = "" then None
|
||||
else if trimmedLine.[0] = '.' then
|
||||
Some {
|
||||
line_no = lineNo;
|
||||
label = None;
|
||||
opcode = "COMMENT";
|
||||
operand = [];
|
||||
comment = Some trimmedLine ;
|
||||
loc = None;
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
(*razdelimo na kodo in komentar za njo*)
|
||||
let code, (comment : string option) =
|
||||
match String.index_opt line '.' with
|
||||
| None -> line, None
|
||||
| Some i ->
|
||||
(*izluščimo komentar in komentarju odstranimo predhodnje presledke*)
|
||||
let c = String.sub line i (String.length line - i) |> String.trim in
|
||||
(*izluščimo kodo, je pa ne trimamo, ker rabimo prvo presledek da razločimo opcode od label-a*)
|
||||
let code = String.sub line 0 i in
|
||||
code, Some c
|
||||
in
|
||||
|
||||
let tokens =
|
||||
code
|
||||
|> String.map (fun c -> if c = ',' then ' ' else c) (*zamenja , z ' ' da lepo parsamo npr RMO A, B*)
|
||||
|> String.split_on_char ' '
|
||||
|> List.map String.trim (* removes surrounding spaces and \r *)
|
||||
|> List.filter (fun s -> s <> "") in
|
||||
match tokens with
|
||||
| [] ->
|
||||
Some{
|
||||
line_no = lineNo;
|
||||
label = None;
|
||||
opcode = "";
|
||||
operand = [];
|
||||
comment;
|
||||
loc = None;
|
||||
}
|
||||
| x :: xs ->
|
||||
if code.[0] <> ' ' && code.[0] <> '\t' then (*pogledamo whitespace ali tab*)
|
||||
(*se ne začne z presledkom ali tab -> imamo labelo*)
|
||||
let label = Some x in
|
||||
match xs with
|
||||
(*samo labela*)
|
||||
| [] -> Some{line_no = lineNo; label = label; opcode = ""; operand = []; comment = comment; loc = None}
|
||||
(*labela + opcode + še nekaj*)
|
||||
| opcode :: operand ->
|
||||
Some{line_no = lineNo; label = label;opcode = opcode; operand = operand; comment = comment; loc = None}
|
||||
else
|
||||
(*nimamo labele*)
|
||||
let opcode = x in
|
||||
let operand = xs in
|
||||
Some{line_no = lineNo; label = None; opcode = opcode; operand = operand; comment = comment; loc = None}
|
||||
|
||||
(*naredi listo line-ov iz filename*)
|
||||
let parser (filename : string) : line list =
|
||||
let ic = open_in filename in
|
||||
let rec loop line_no acc =
|
||||
match input_line ic with
|
||||
| line ->
|
||||
begin
|
||||
match parseLine line_no line with
|
||||
| Some parsed_line -> loop (line_no + 1) (parsed_line :: acc)
|
||||
| None -> loop (line_no + 1) acc
|
||||
end
|
||||
| exception End_of_file ->
|
||||
close_in ic;
|
||||
List.rev acc
|
||||
in
|
||||
loop 1 []
|
||||
Loading…
Add table
Add a link
Reference in a new issue