The Compiler Generator Coco/R

来源:互联网 发布:win10怎么安装mysql 编辑:程序博客网 时间:2024/04/30 09:09

网站:http://ssw.jku.at/Coco/

As mentioned, check out the available parser generators to do real work with parsers.

  • Coco/R: http://ssw.jku.at/Coco/
  • ANTLR: http://www.antlr.org/

Coco/R is a compiler generator, which takes an attributed grammar of a source language and generates a scanner and a parser for this language. The scanner works as a deterministic finite automaton. The parser uses recursive descent. LL(1) conflicts can be resolved by a multi-symbol lookahead or by semantic checks. Thus the class of accepted grammars is LL(k) for an arbitrary k.

基于Coco/R的数学表达式计算应用:http://www.codeproject.com/Articles/343646/Mathematical-Expression-Parser-Using-Coco-R

 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions;  using ValueList = System.Collections.Generic.List<double>;  namespace ExpressionParser {     public class ManParser     {         // --------------------------- custom code ----------------------          private double Eval(string name, ValueList args)         {             string symbol = args == null ? name : string.Format("{0}({1})", name, args.Count);             Func<ValueList, double> func;             if (_symbols.TryGetValue(symbol, out func)) return func(args);             Error(string.Format("Symbol not found: {0}", name));             return double.PositiveInfinity;         }          private double Eval(string name, params double[] args)         {             return Eval(name, new ValueList(args));         }          public static void SetVar(string name, double val)         {             if (_symbols.ContainsKey(name)) _symbols[name] = a => val;             else _symbols.Add(name, a => val);         }          private const double DEG_RAD = Math.PI / 180.0;          private static Dictionary<string, Func<ValueList, double>> _symbols =         new Dictionary<string, Func<ValueList, double>>(StringComparer.InvariantCultureIgnoreCase)         {             { "+(2)", a=> a[0]+a[1] },             { "-(2)", a=> a[0]-a[1] },             { "*(2)", a=> a[0]*a[1] },             { "/(2)", a=> a[0]/a[1] },             { "%(2)", a=> a[0]%a[1] },             { "^(2)", a=> Math.Pow(a[0],a[1]) },             { "!(1)", a=> {double v=a[0]; int i = (int)v; while(--i > 0) v*=i; return v;} },             { "-(1)", a=> -a[0] },             { "(1)", a=> a[0] },             { "pi", a=> Math.PI },             { "sin(1)", a=> Math.Sin(DEG_RAD*a[0]) },             { "cos(1)", a=> Math.Cos(DEG_RAD*a[0]) },             { "tan(1)", a=> Math.Tan(DEG_RAD*a[0]) },             { "exp(1)", a=> Math.Exp(a[0]) },             { "ln(1)", a=> Math.Log(a[0]) },             { "log(1)", a=> Math.Log10(a[0]) },         };          public static double Evaluate(string s) { return new ManParser(s).Expr(); }          // ------------------- scanner ---------------------         private IEnumerator<Match> _tokens;         private bool Next() { return _valid && (_valid = _tokens.MoveNext()); }         private string Curr { get { return _valid ? _tokens.Current.Groups[1].Value : null; } }         private int Pos { get { return _valid ? _tokens.Current.Index : 0; } }         private bool _valid = true;         private TextWriter _errout;         private void Error(string msg, params object[] args)         { _errout.Write("error: " + msg, args); _errout.WriteLine(" (at {0}: '{1}')", Pos, Curr ?? ""); }          // -------------------- parser ------------------------         public ManParser(string s)         {             _errout = Console.Error;             string p = @"\s*((?:[\-\+\*\/\%\!\(\)]|(?:\d+(?:\.\d+)?)|\w+)|(?:\S))\s*";             _tokens = Regex.Matches(s, p, RegexOptions.Compiled).Cast<Match>().GetEnumerator(); ;             Next();         }         private double Expr()         {             string[] ops = new [] { "+", "-" };             string op;             double v = Term();             while (ops.Contains(op = Curr) && Next()) v = Eval(op, v, Term());             while (Curr == "!") { v = Eval("!", v); Next(); }             return v;         }         private double Term()         {             string[] ops = new[] { "*", "/", "%", "^" };             string op;             double v = Factor();             while (ops.Contains(op = Curr) && Next()) v = Eval(op, v, Factor());             return v;         }         private double Factor()         {             string s = Curr;             char c = s[0];             if      (char.IsDigit(c))                      return Number();             else if ((char.IsLower(c) || char.IsUpper(c))) return Name();             else if (c == '(')                             return NestedExpr();             else Error("name, number or (...) expected");             return double.PositiveInfinity;         }         private double Number()         {             double v = double.Parse(Curr);             Next();             return v;         }         private double Name()         {             string name = Curr;             ValueList args = null;             if (Next()) if (Curr == "(") { args = ArgList(); }             return Eval(name, args);         }         private ValueList ArgList()         {             ValueList args = new ValueList();             if (Curr != "(") Error("'(' expected");             if (Next() && Curr != ")") { args.Add(Expr()); while (Curr == "," && Next()) args.Add(Expr()); }             if (Curr != ")") Error("')' expected");             Next();             return args;         }         private double NestedExpr()         {             if (Curr != "(") Error("'(' expected");             if (!Next()) Error("unexpected EOF");             double v = (Curr == "-" && Next()) ? -Expr() : Expr();             if (Curr != ")") Error("')' expected");             Next();             return v;         }     } }
具体看网页内容


0 0
原创粉丝点击