具有讽刺意味 - 样本表达式计算器 1.0 - "iff"符号在哪里定义?



我正在使用Irony repo中提供的语法资源管理器。我试图了解事情是如何运作的。我很困惑。我似乎找不到 iff 符号在 SampleExpressionEvaluator 1.0 示例中定义的位置 - "testlif.txt">

iif(1 > 0, "true", 1/0) + ", " + (1 > 0 ? "true" : 1/0) # expected: true, true

如果我iff更改为blah,我会得到一个Error: Unknown symbol 'blah'. At (4:1).,这让我假设iff是在我无法弄清楚在哪里的地方定义的。

这是语法定义

[Language("ExpressionEvaluator", "1.0", "Multi-line expression evaluator")]
public class ExpressionEvaluatorGrammar : InterpretedLanguageGrammar {
public ExpressionEvaluatorGrammar() : base(caseSensitive: false) { 
this.GrammarComments = 
@"Irony expression evaluator. Case-insensitive. Supports big integers, float data types, variables, assignments,
arithmetic operations, augmented assignments (+=, -=), inc/dec (++,--), strings with embedded expressions; 
bool operations &,&&, |, ||; ternary '?:' operator." ;
// 1. Terminals
var number = new NumberLiteral("number");
//Let's allow big integers (with unlimited number of digits):
number.DefaultIntTypes = new TypeCode[] { TypeCode.Int32, TypeCode.Int64, NumberLiteral.TypeCodeBigInt };
var identifier = new IdentifierTerminal("identifier");
var comment = new CommentTerminal("comment", "#", "n", "r"); 
//comment must be added to NonGrammarTerminals list; it is not used directly in grammar rules,
// so we add it to this list to let Scanner know that it is also a valid terminal. 
base.NonGrammarTerminals.Add(comment);
var comma = ToTerm(",");
//String literal with embedded expressions  ------------------------------------------------------------------
var stringLit = new StringLiteral("string", """, StringOptions.AllowsAllEscapes | StringOptions.IsTemplate);
stringLit.AddStartEnd("'", StringOptions.AllowsAllEscapes | StringOptions.IsTemplate); 
stringLit.AstConfig.NodeType = typeof(StringTemplateNode);
var Expr = new NonTerminal("Expr"); //declare it here to use in template definition 
var templateSettings = new StringTemplateSettings(); //by default set to Ruby-style settings 
templateSettings.ExpressionRoot = Expr; //this defines how to evaluate expressions inside template
this.SnippetRoots.Add(Expr);
stringLit.AstConfig.Data = templateSettings;
//--------------------------------------------------------------------------------------------------------
// 2. Non-terminals
var Term = new NonTerminal("Term");
var BinExpr = new NonTerminal("BinExpr", typeof(BinaryOperationNode));
var ParExpr = new NonTerminal("ParExpr");
var UnExpr = new NonTerminal("UnExpr", typeof(UnaryOperationNode));
var TernaryIfExpr = new NonTerminal("TernaryIf", typeof(IfNode));
var ArgList = new NonTerminal("ArgList", typeof(ExpressionListNode));
var FunctionCall = new NonTerminal("FunctionCall", typeof(FunctionCallNode));
var MemberAccess = new NonTerminal("MemberAccess", typeof(MemberAccessNode));
var IndexedAccess = new NonTerminal("IndexedAccess", typeof(IndexedAccessNode));
var ObjectRef = new NonTerminal("ObjectRef"); // foo, foo.bar or f['bar']
var UnOp = new NonTerminal("UnOp");
var BinOp = new NonTerminal("BinOp", "operator");
var PrefixIncDec = new NonTerminal("PrefixIncDec", typeof(IncDecNode));
var PostfixIncDec = new NonTerminal("PostfixIncDec", typeof(IncDecNode));
var IncDecOp = new NonTerminal("IncDecOp");
var AssignmentStmt = new NonTerminal("AssignmentStmt", typeof(AssignmentNode));
var AssignmentOp = new NonTerminal("AssignmentOp", "assignment operator");
var Statement = new NonTerminal("Statement");
var Program = new NonTerminal("Program", typeof(StatementListNode));
// 3. BNF rules
Expr.Rule = Term | UnExpr | BinExpr | PrefixIncDec | PostfixIncDec | TernaryIfExpr;
Term.Rule = number | ParExpr | stringLit | FunctionCall | identifier | MemberAccess | IndexedAccess;
ParExpr.Rule = "(" + Expr + ")";
UnExpr.Rule = UnOp + Term + ReduceHere();
UnOp.Rule = ToTerm("+") | "-" | "!"; 
BinExpr.Rule = Expr + BinOp + Expr;
BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**" | "==" | "<" | "<=" | ">" | ">=" | "!=" | "&&" | "||" | "&" | "|";
PrefixIncDec.Rule = IncDecOp + identifier;
PostfixIncDec.Rule = identifier + PreferShiftHere() + IncDecOp;
IncDecOp.Rule = ToTerm("++") | "--";
TernaryIfExpr.Rule = Expr + "?" + Expr + ":" + Expr;
MemberAccess.Rule = Expr + PreferShiftHere() + "." + identifier; 
AssignmentStmt.Rule = ObjectRef + AssignmentOp + Expr;
AssignmentOp.Rule = ToTerm("=") | "+=" | "-=" | "*=" | "/=";
Statement.Rule = AssignmentStmt | Expr | Empty;
ArgList.Rule = MakeStarRule(ArgList, comma, Expr);
FunctionCall.Rule = Expr + PreferShiftHere() + "(" + ArgList + ")";
FunctionCall.NodeCaptionTemplate = "call #{0}(...)";
ObjectRef.Rule = identifier | MemberAccess | IndexedAccess;
IndexedAccess.Rule = Expr + PreferShiftHere() + "[" + Expr + "]";
Program.Rule = MakePlusRule(Program, NewLine, Statement);
this.Root = Program;       // Set grammar root
// 4. Operators precedence
RegisterOperators(10, "?");
RegisterOperators(15, "&", "&&", "|", "||");
RegisterOperators(20, "==", "<", "<=", ">", ">=", "!=");
RegisterOperators(30, "+", "-");
RegisterOperators(40, "*", "/");
RegisterOperators(50, Associativity.Right, "**");
RegisterOperators(60, "!");
// For precedence to work, we need to take care of one more thing: BinOp. 
//For BinOp which is or-combination of binary operators, we need to either 
// 1) mark it transient or 2) set flag TermFlags.InheritPrecedence
// We use first option, making it Transient.  
// 5. Punctuation and transient terms
MarkPunctuation("(", ")", "?", ":", "[", "]");
RegisterBracePair("(", ")");
RegisterBracePair("[", "]");
MarkTransient(Term, Expr, Statement, BinOp, UnOp, IncDecOp, AssignmentOp, ParExpr, ObjectRef);
// 7. Syntax error reporting
MarkNotReported("++", "--");
AddToNoReportGroup("(", "++", "--");
AddToNoReportGroup(NewLine);
AddOperatorReportGroup("operator");
AddTermsReportGroup("assignment operator", "=", "+=", "-=", "*=", "/=");
//8. Console
ConsoleTitle = "Irony Expression Evaluator";
ConsoleGreeting =
@"Irony Expression Evaluator 
Supports variable assignments, arithmetic operators (+, -, *, /),
augmented assignments (+=, -=, etc), prefix/postfix operators ++,--, string operations. 
Supports big integer arithmetics, string operations.
Supports strings with embedded expressions : ""name: #{name}""
Press Ctrl-C to exit the program at any time.
";
ConsolePrompt = "?";
ConsolePromptMoreInput = "?";
//9. Language flags. 
// Automatically add NewLine before EOF so that our BNF rules work correctly when there's no final line break in source
this.LanguageFlags = LanguageFlags.NewLineBeforeEOF | LanguageFlags.CreateAst | LanguageFlags.SupportsBigInt;
}

我希望解析现有的专有字符串表达式语言。这个样本似乎是最相关的,但这个样本让我感到困惑。

示例字符串文本将Hello I am Feeling {IF(boolMoodIsGood = True, "Good","Bad")}如果boolMoodIsGood是真的,结果将是Hello I am Feeling GoodHello I am Feeling Bad

但实际上我不需要计算表达式,我只需要解析它并获取表达式树。

查看ExpressionEvaluatorRuntime类。

最新更新