using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using glue.Tokenization; using glue; namespace agree.Parse { public class ParserConfiguration : INotifyPropertyChanged { static readonly Char[] dot_space = new Char[] { '.', ' ' }; /// <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, }; bool f_irregular_forms_only = false; KeyStrategy key_strategy = KeyStrategy.KeyDriven; Double timeout_sec = Double.MaxValue; Type T_tokenizer = typeof(SpaceCharTokenizer); DependencyScope chart_dependency_scope = DependencyScope.TwoWay; KeyValuePair<String[], String[]>[] chart_dependency_paths = null; /// <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 Type 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 KeyValuePair<String[], String[]>( kvp.Key.Trim('\"').Split(dot_space), kvp.Value.Trim('\"').Split(dot_space))) .ToArray(); if (chart_dependency_paths.Length == 0) chart_dependency_paths = null; NotifyPropertyChanged("ChartDependencyPaths"); } } public KeyValuePair<String[], String[]>[] 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 NodeLabelConfiguration : INotifyPropertyChanged { static readonly String[] rg_string_empty = new String[0]; static readonly Char[] dot_space = new Char[] { '.', ' ' }; bool simple_tree_display = false; String[] label_path = null; String[] prefix_path = null; String[] suffix_path = null; String[] recursive_path = null; String[] local_path = null; String[] 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"); } } } bool CheckAndCleanPath(ref String[] path, ref String[] new_value) { if (new_value != null) new_value = new_value.Where(s => !String.IsNullOrWhiteSpace(s.Trim(dot_space))).ToArray(); else new_value = rg_string_empty; if (path == new_value || (path != null && path.SequenceEqual(new_value))) return false; path = new_value; return true; } public String[] LabelPath { get { return label_path; } set { if (simple_tree_display) throw new Exception("Cannot specify 'LabelPath' when using 'SimpleTreeDisplay'"); if (value == label_path) return; if (CheckAndCleanPath(ref label_path, ref value)) { NotifyPropertyChanged("LabelPath"); } } } public String[] PrefixPath { get { return prefix_path; } set { if (simple_tree_display) throw new Exception("Cannot specify 'PrefixPath' when using 'SimpleTreeDisplay'"); if (value == prefix_path) return; if (CheckAndCleanPath(ref prefix_path, ref value)) { NotifyPropertyChanged("PrefixPath"); } } } public String[] SuffixPath { get { return suffix_path; } set { if (simple_tree_display) throw new Exception("Cannot specify 'SuffixPath' when using 'SimpleTreeDisplay'"); if (value == suffix_path) return; if (CheckAndCleanPath(ref suffix_path, ref value)) { NotifyPropertyChanged("SuffixPath"); } } } public String[] RecursivePath { get { return recursive_path; } set { if (simple_tree_display) throw new Exception("Cannot specify 'RecursivePath' when using 'SimpleTreeDisplay'"); if (value == recursive_path) return; if (CheckAndCleanPath(ref recursive_path, ref value)) { NotifyPropertyChanged("RecursivePath"); } } } public String[] LocalPath { get { return local_path; } set { if (simple_tree_display) throw new Exception("Cannot specify 'LocalPath' when using 'SimpleTreeDisplay'"); if (value == local_path) return; if (CheckAndCleanPath(ref local_path, ref value)) { NotifyPropertyChanged("LocalPath"); } } } public String[] 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) return; if (CheckAndCleanPath(ref label_fs_path, ref 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)); } }; }