syntax error...

Feb 27, 2012 at 8:22 PM

Here's part of my code that works to parse something like this: 

Container^AccountCode LIKE "A" AND Container^ItemCode = "C0000009"

var number = new NumberLiteral("number");
var stringLiteral = new StringLiteral("string");
stringLiteral.AddStartEnd("\"", StringOptions.NoEscapes);
var identifier = new IdentifierTerminal("identifier");
var file = CreateCustomIdentifier(this, "file");
var field = CreateCustomIdentifier(this, "field");

var comma = ToTerm(",");
var caret = ToTerm("^");

var Expr = new NonTerminal("expression");
var Column = new NonTerminal("Column", typeof(ColumnNode));
var BinExpr = new NonTerminal("Binexpr", typeof(BinaryOperationNode));
var ParExpr = new NonTerminal("parexpr");
var FunctionCall = new NonTerminal("FunctionCall", typeof(FunctionCallNode));
var Constant = new NonTerminal("Constant", typeof(LiteralValueNode));
var BinOp = new NonTerminal("binop", "operator");
var UnExpr = new NonTerminal("UnExpr", typeof(UnaryOperationNode));
var ArgList = new NonTerminal("ArgList", typeof(ExpressionListNode));
var UnOp = new NonTerminal("unop", "operator");

// BNF rules
this.Root = Expr;

// components of an expressions
Constant.Rule = number | stringLiteral;
Column.Rule = file + caret + field;// | field;

---- ...

Now to make it work on a slight deviation such as:

AccountCode LIKE "A" AND Container^ItemCode = "C0000009"

I change the last line (shown above) to this:

Column.Rule = file + caret + field | field;
but that gives me a syntax error. Can someone explain why this is? What am I missing?

Feb 27, 2012 at 8:27 PM
Edited Feb 27, 2012 at 8:28 PM

it probably scans the stand-alone custom identifier as a "file", not field. You have to resolve this somehow. One suggestion - can you use the same terminal "field" for both? It does not seem they are actually different internally, you use the same CreateCustomIdentifier method. So the scanner would produce "field" token for both cases, and then the Parser would recognize what is this based on grammar rules. 

Feb 27, 2012 at 8:30 PM

OK, I'll experiment with that. 

Thanks for your quick response!

Mar 1, 2012 at 6:18 PM

so here's another issue that I have with the way the order of parsing works, 

// components of an expressions
Constant.Rule = number | stringLiteral;
Column.Rule = (columnPart + caret + columnPart) | columnPart;
FunctionCall.Rule = identifier + "(" + ArgList + ")";
FunctionCall.NodeCaptionTemplate = "call #{0}(...)";
ArgList.Rule = MakeStarRule(ArgList, comma, Expr);

Expr.Rule = UnExpr | BinExpr | Column | Constant | FunctionCall | ParExpr;

the problem is when I have something like this:

Container^Date < CurDate()

as it tries to parse CurDate() it expects a column and gets thrown off when it sees a '(' ...

I am a bit new to this, but isn't it supposed to follow the path of no error,

Mar 2, 2012 at 6:32 PM

I think it's the same kind of problem as before - is columnPart declared as Identifier? The trouble is that Scanner has several "identifiers" to choose from, they are all the same, and it has no knowledge which one is which. Parser can help scanner sometimes (tell it what is expected in this position), but in your case both are expected - function name or columnPart, so scanner make arbitrary decision.

Make sure you have a single IdentifierTerminal declared in grammar and reuse it in all expressions.