~cypheon/kicad2spice

ref: 96e390bc4f914314da98ecdfd7bd775e620563e2 kicad2spice/lib/sch_legacy.mly -rw-r--r-- 3.7 KiB
96e390bc — Johann Rudloff Implement correct pin order according to field "Spice_Node_Sequence" 3 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
%token MAGIC_HEADER
%token <int> INT
%token <string> STRING
%token <string> STRING_UNQUOTED
%token <string * string> WIRE
%token NEWLINE
%token EOF
%token <string> LIBS
%token EELAYER
%token END
%token ENCODING
%token <string> CONNECTION
%token SHEET
%token <string> START_DESCR
%token END_DESCR
%token END_SCHEMATIC
%token <string list> COMPONENT

%{

open Schematic
open Sch_legacy_ast

let rec comp_parse_start lines = match lines with
  | ("L"::name::ref::[])::rest -> comp_parse_unique name ref rest
  | _ -> failwith "unexpected EOF, expecting \"L\" line"
and comp_parse_unique name ref lines = match lines with
  | ("U"::_)::rest -> comp_parse_pos name ref rest
  | _ -> failwith "unexpected EOF, expecting \"U\" line"
and comp_parse_pos name ref lines = match lines with
  | ("P"::x::y::[])::rest -> comp_parse_fields name ref {Geometry. x=int_of_string x;y=int_of_string y} rest
  | _ -> failwith "unexpected EOF, expecting \"P\" line"
and comp_parse_fields name ref pos lines = match lines with
  | ("F"::"0"::_)::rest -> comp_parse_fields name ref pos rest
  | ("F"::"1"::value::_)::rest -> comp_parse_extra1 name ref pos value (Fields.empty) rest
  | _ -> failwith "unexpected EOF, expecting \"F\" line"
and comp_parse_extra1 name ref pos value fields lines = match lines with
  | ("F"::tokens)::rest ->
      let updated_fields = if List.length tokens >= 10 then
        let f_name = List.nth tokens 9 in
        let f_value = List.nth tokens 1 in
        (Fields.add f_name f_value fields)
      else fields in
      comp_parse_extra1 name ref pos value updated_fields rest
  | ("\t"::_)::rest -> comp_parse_extra2 name ref pos value fields rest
  | _ -> failwith "unexpected EOF, expecting indented line"
and comp_parse_extra2 name ref pos value fields lines = match lines with
  | ("\t"::a::b::c::d::[])::[] -> let
  a,b,c,d = (int_of_string a, int_of_string b, int_of_string c, int_of_string d)
  in {ParserComp.
    name; ref; value; pos; transform={a;b;c;d}; fields;
    }
  | _ -> failwith "unexpected EOF, expecting indented line"

let prepare_line line = match line.[0] with
    '\t' -> "\t"::(Lex_tokenize.tokenize line)
  | _ -> Lex_tokenize.tokenize line

let component_from_lines lines = comp_parse_start (List.map prepare_line lines)

let junction_from_string line = match (Lex_tokenize.tokenize line) with
  | ["Connection";"~";posx;posy] -> {Junction.pos={x=int_of_string posx;y=int_of_string posy}}
  | _ -> failwith "Invalid Junction definition"

let wire_from_string wire_type wire_pos =
  let type_tokens = Lex_tokenize.tokenize wire_type in
  let pos_tokens = List.map int_of_string (Lex_tokenize.tokenize wire_pos) in
  match type_tokens with
  ["Wire"; "Wire"; "Line"] ->
    {Schematic.Wire.
      startp = {x = List.nth pos_tokens 0; y = List.nth pos_tokens 1};
      endp = {x = List.nth pos_tokens 2; y = List.nth pos_tokens 3};
    }
  | _ -> failwith ("unsupported wire type:" ^ wire_type)

%}

%start <int * Sch_legacy_ast.ParserItem.t list> main
%start <string list> tokenize

%%

item:
  | comp = COMPONENT { ParserItem.Comp (component_from_lines comp) }
  | junc = CONNECTION { Junction (junction_from_string junc) }
  | wire = WIRE { let (wt, wp) = wire in ParserItem.Wire (wire_from_string wt wp) }
kv_pair:
  | key = STRING_UNQUOTED; value = STRING; NEWLINE { (key, value) }
main:
  | MAGIC_HEADER; version = INT; NEWLINE;
    LIBS; NEWLINE;
    EELAYER; INT; INT; NEWLINE;
    EELAYER; END; NEWLINE;

    START_DESCR; NEWLINE;
    ENCODING; STRING_UNQUOTED; NEWLINE;
    SHEET; INT; INT; NEWLINE;
    list(kv_pair);
    END_DESCR; NEWLINE;

    items = list(item);
    END_SCHEMATIC; list(NEWLINE); EOF
    { (version, items) }
  ;
token:
  | s = STRING { s }
  | s = STRING_UNQUOTED { s }
tokenize:
  | tokens = list(token); EOF { tokens }