420 object Parsers extends Parsers |
420 object Parsers extends Parsers |
421 |
421 |
422 |
422 |
423 /* checking and translating parse structure into toml */ |
423 /* checking and translating parse structure into toml */ |
424 |
424 |
425 class Parse_Context private(var seen_tables: Map[Parsers.Keys, Seen]) { |
425 class Parse_Context private(var seen_tables: Map[Parsers.Keys, Seen], file: Option[Path] = None) { |
426 private def recent_array(ks: Parsers.Keys): (Parsers.Keys, Seen, Parsers.Keys) = |
426 private def recent_array(ks: Parsers.Keys): (Parsers.Keys, Seen, Parsers.Keys) = |
427 ks.splits.collectFirst { |
427 ks.splits.collectFirst { |
428 case (ks1, ks2) if seen_tables.contains(ks1) => (ks1, seen_tables(ks1), ks2) |
428 case (ks1, ks2) if seen_tables.contains(ks1) => (ks1, seen_tables(ks1), ks2) |
429 }.get |
429 }.get |
430 |
430 |
465 case _: Parsers.Array_Of_Tables => (Set.empty, Set.empty) |
465 case _: Parsers.Array_Of_Tables => (Set.empty, Set.empty) |
466 } |
466 } |
467 |
467 |
468 seen_tables += to -> Seen(inlines, tables) |
468 seen_tables += to -> Seen(inlines, tables) |
469 } |
469 } |
470 def error[A](s: Str, ks: Parsers.Keys, elem: Positional): A = |
470 |
471 isabelle.error(s + " in table " + Format.keys(ks.rep) + " at line " + elem.pos.line) |
471 def for_file(file: Path): Parse_Context = new Parse_Context(seen_tables, Some(file)) |
|
472 |
|
473 def error[A](s: Str, ks: Parsers.Keys, elem: Positional): A = { |
|
474 val file_msg = if_proper(file, " in " + file.get) |
|
475 isabelle.error( |
|
476 s + " in table " + Format.keys(ks.rep) + " at line " + elem.pos.line + file_msg) |
|
477 } |
|
478 |
472 def check_add_def(ks: Parsers.Keys, defn: Parsers.Def): Unit = check_add(0, ks, defn) |
479 def check_add_def(ks: Parsers.Keys, defn: Parsers.Def): Unit = check_add(0, ks, defn) |
473 def check_add_value(ks0: Parsers.Keys, ks1: Parsers.Keys, v: Parsers.V): Unit = |
480 def check_add_value(ks0: Parsers.Keys, ks1: Parsers.Keys, v: Parsers.V): Unit = |
474 check_add(ks0.length - 1, ks0 + ks1, v) |
481 check_add(ks0.length - 1, ks0 + ks1, v) |
475 } |
482 } |
476 |
483 |
564 update(t0, ks0, Array(fold(elems.map((ks, v) => (ks, convert(ks0, ks, v)))))) |
571 update(t0, ks0, Array(fold(elems.map((ks, v) => (ks, convert(ks0, ks, v)))))) |
565 } |
572 } |
566 } |
573 } |
567 |
574 |
568 def parse_files(files: Iterable[Path], context: Parse_Context = Parse_Context()): Table = |
575 def parse_files(files: Iterable[Path], context: Parse_Context = Parse_Context()): Table = |
569 files.map(File.read).map(parse(_, context)).foldLeft(Table())(_ ++ _) |
576 files.foldLeft((Table(), context)) { |
|
577 case ((t, context0), file) => |
|
578 val context = context0.for_file(file) |
|
579 (t ++ parse(File.read(file), context), context) |
|
580 }._1 |
570 |
581 |
571 |
582 |
572 /* Format TOML */ |
583 /* Format TOML */ |
573 |
584 |
574 object Format { |
585 object Format { |