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