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));
}
};
}