using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using miew.Tokenization; using miew.Reflection; using miew.Enumerable; namespace agree { using SysType = System.Type; public sealed partial class Config { public sealed class Parser : INotifyPropertyChanged { /// <summary> /// Options for configuring which rule daughter the parser will try to unify first /// </summary> public enum KeyStrategy { /// <summary> /// The parser will unify the rule daughter whose key feature (configurable) has a certain key /// value (configurable) /// </summary> KeyDriven, // use, e.g. KEY-ARG + /// <summary> /// The parser will unify rule daughters left-to-right /// </summary> LeftToRight, /// <summary> /// The parser will unify rule daughters right-to-left /// </summary> RightToLeft, /// <summary> /// The parser will unify the rule daughter that is designated as the head daughter /// </summary> HeadDaughter, // use, e.g. HD-DTR (todo) }; public enum DependencyScope { Unidirectional, TwoWay, }; Config cfg; public Parser(Config cfg) { this.cfg = cfg; } public Config _cfg { get { return cfg; } } public HashSet<Char> punctuation_chars = new HashSet<char>(); public bool f_irregular_forms_only = false; public bool f_lex_entries_can_fail = false; public bool f_case_sensitive = false; KeyStrategy key_strategy = KeyStrategy.KeyDriven; Double timeout_sec = Double.MaxValue; SysType T_tokenizer = typeof(SpaceCharTokenizer); DependencyScope chart_dependency_scope = DependencyScope.TwoWay; FsPathPair[] chart_dependency_paths = null; public List<String> deleted_daughters = null; public List<String> packing_restrictors = null; public byte[] deleted_daughter_map; public QuickCheckStrategy qcs; public enum UnifierType { Incremental, n_way, qd, } public UnifierType unifier = UnifierType.n_way; public UnifierType checker = UnifierType.n_way; [Flags] public enum PackingOpts : sbyte { None = 0, Proactive = 1, Retroactive = 2, Equivalence = 3, Full = Equivalence, Only = 4, ProactiveOnly = Proactive | Only, RetroactiveOnly = Retroactive | Only, EquivalenceOnly = Equivalence | Only, }; public PackingOpts packing = PackingOpts.None;//PackingOpts.Full; public byte[] packing_restrictor_map; public bool f_variadic_unpack = false; public TypeMgrCompiledFsPath RuleArgsPath; public TypeMgrCompiledFsPath KeyDaughterPath; public TypeMgrCompiledFsPath OrthPath; public List<String> span_only_rules = null; public int chart_limit = 100; public int max_edges = 4000; public bool f_qc_morph = true; public bool f_qc_parse = true; public List<String> s_quick_check_paths; public bool f_autotune = false; public int[] DeletedDaughters; public int c_tasks_max = int.MaxValue; public void CompileGrammarPaths(TypeMgr tm) { Config gc = tm.config; RuleArgsPath = new TypeMgrCompiledFsPath(tm, gc.grammar.rule_args_path); KeyDaughterPath = new TypeMgrCompiledFsPath(tm, gc.grammar.key_daughter_path); OrthPath = new TypeMgrCompiledFsPath(tm, gc.grammar.orth_path); //UnificationQd.arg0_path = RuleArgsPath.Append(tm.f_ix_list_head).ToArray(); //UnificationQd.arg1_path = RuleArgsPath.Append(tm.f_ix_list_tail).Append(tm.f_ix_list_head).ToArray(); if (deleted_daughters != null) { int[] rgdd = deleted_daughters.Select(s => tm.feat_map[s].i_feat).ToArray(); deleted_daughter_map = new byte[tm.feat_arr.Length]; foreach (int i_feat in rgdd) deleted_daughter_map[i_feat] = 1; DeletedDaughters = rgdd; } if (packing_restrictors != null) { packing_restrictor_map = new byte[tm.feat_arr.Length]; foreach (int i_feat in packing_restrictors.Select(s => tm.feat_map[s].i_feat)) packing_restrictor_map[i_feat] = 1; } if ((f_qc_parse || f_qc_morph) && s_quick_check_paths != null && s_quick_check_paths.Count > 0) qcs = new QuickCheckStrategy(tm, s_quick_check_paths); } /// <summary> /// Strategy used by the parser to determine which of a mother rule's unifications to perform /// first. The available options are documented in ParseConfiguration.KeyStrategy /// </summary> public KeyStrategy ParsingStrategy { get { return key_strategy; } set { if (value != key_strategy) { key_strategy = value; NotifyPropertyChanged("ParsingStrategy"); } } } /// <summary> /// If 'true', the presence of an irregular form in a morphological analysis hypothesis will /// block the proposal of any regularly inflected forms. /// </summary> public bool IrregularFormsOnly { get { return f_irregular_forms_only; } set { if (value != f_irregular_forms_only) { f_irregular_forms_only = value; NotifyPropertyChanged("IrregularFormsOnly"); } } } /// <summary> /// Number of seconds allowed per parse. If the parse is not complete within this amount of time, /// the parse will be aborted with a ParseTimeoutException. /// </summary> public Double ItemTimeoutSeconds { get { return timeout_sec; } set { if (value != timeout_sec) { timeout_sec = value; NotifyPropertyChanged("TimeoutSeconds"); } } } public SysType TokenizerType { get { return T_tokenizer; } set { if (value == null) throw new ArgumentNullException(); if (!value.HasInterface(typeof(ITokenizer))) throw new ArgumentException("Tokenizer type must be derived from ITokenizer"); if (value != T_tokenizer) { T_tokenizer = value; NotifyPropertyChanged("TokenizerType"); } } } public DependencyScope ChartDependencyScope { get { return chart_dependency_scope; } set { if (value != chart_dependency_scope) { chart_dependency_scope = value; NotifyPropertyChanged("ChartDependencyScope"); } } } public IEnumerable<KeyValuePair<String, String>> ChartDependencyPaths { set { chart_dependency_paths = value.Select(kvp => new FsPathPair(kvp.Key, kvp.Value)).ToArray(); if (chart_dependency_paths.Length == 0) chart_dependency_paths = null; NotifyPropertyChanged("ChartDependencyPaths"); } } public FsPathPair[] ChartDependencyPathsArray { get { return chart_dependency_paths; } } public event PropertyChangedEventHandler PropertyChanged; /// <summary> /// Notify interested parties that a configuration option has changed. /// </summary> void NotifyPropertyChanged(String s_field) { var h = PropertyChanged; if (h != null) h(this, new PropertyChangedEventArgs(s_field)); } }; public class NodeLabels : INotifyPropertyChanged { bool simple_tree_display = false; FsPath label_path = null; FsPath prefix_path = null; FsPath suffix_path = null; FsPath recursive_path = null; FsPath local_path = null; FsPath label_fs_path = null; String label_template_type = null; String meta_template_type = "meta"; public bool SimpleTreeDisplay { get { return simple_tree_display; } set { if (value != simple_tree_display) { simple_tree_display = value; NotifyPropertyChanged("SimpleTreeDisplay"); } } } public FsPath LabelPath { get { return label_path; } set { if (simple_tree_display) throw new Exception("Cannot specify 'LabelPath' when using 'SimpleTreeDisplay'"); if (value != label_path) { label_path = value; NotifyPropertyChanged("LabelPath"); } } } public FsPath PrefixPath { get { return prefix_path; } set { if (simple_tree_display) throw new Exception("Cannot specify 'PrefixPath' when using 'SimpleTreeDisplay'"); if (value != prefix_path) { prefix_path = value; NotifyPropertyChanged("PrefixPath"); } } } public FsPath SuffixPath { get { return suffix_path; } set { if (simple_tree_display) throw new Exception("Cannot specify 'SuffixPath' when using 'SimpleTreeDisplay'"); if (value != suffix_path) { suffix_path = value; NotifyPropertyChanged("SuffixPath"); } } } public FsPath RecursivePath { get { return recursive_path; } set { if (simple_tree_display) throw new Exception("Cannot specify 'RecursivePath' when using 'SimpleTreeDisplay'"); if (value != recursive_path) { recursive_path = value; NotifyPropertyChanged("RecursivePath"); } } } public FsPath LocalPath { get { return local_path; } set { if (simple_tree_display) throw new Exception("Cannot specify 'LocalPath' when using 'SimpleTreeDisplay'"); if (value != local_path) { local_path = value; NotifyPropertyChanged("LocalPath"); } } } public FsPath LabelFsPath { get { return label_fs_path; } set { if (simple_tree_display) throw new Exception("Cannot specify 'LabelFsPath' when using 'SimpleTreeDisplay'"); if (value != label_fs_path) { label_fs_path = value; NotifyPropertyChanged("LabelFsPath"); } } } public String LabelTemplateType { get { return label_template_type; } set { if (simple_tree_display) throw new Exception("Cannot specify 'LabelTemplateType' when using 'SimpleTreeDisplay'"); if (value != label_template_type) { label_template_type = value; NotifyPropertyChanged("LabelTemplateType"); } } } public String MetaTemplateType { get { return meta_template_type; } set { if (simple_tree_display) throw new Exception("Cannot specify 'MetaTemplateType' when using 'SimpleTreeDisplay'"); if (value != meta_template_type) { meta_template_type = value; NotifyPropertyChanged("MetaTemplateType"); } } } public event PropertyChangedEventHandler PropertyChanged; /// <summary> /// Notify interested parties that a configuration option has changed. /// </summary> void NotifyPropertyChanged(String s_field) { var h = PropertyChanged; if (h != null) h(this, new PropertyChangedEventArgs(s_field)); } }; }; }