Implementing a prefix notation expression parser using Irony

喜欢而已 提交于 2019-12-21 21:40:04

问题


I'm trying to parse user-inputted prefix notation logical expressions using a context-free-grammar with the Irony library. This is for a class assignment so if anybody happens to be an expert on this, I would love to know more.

I need to accept a user-inputted logical expression of the following format:

and P Q -- (meaning P ^ Q)
or P Q -- (meaning P v Q)
not P  -- (meaning ~P)
imp P Q -- (meaning P -> Q)

I'm attempting to parse these into expression trees using a context free grammar I'm implementing in Irony. The context-free grammar I'm using is here, in BNF:

<Expression> ::= <Not> | <And> | <Or> | <Implies> | <Identifier>
<Not>        ::= "not" <Expression>
<And>        ::= "and" <Expression> <Expression>
<Or>         ::= "or" <Expression> <Expression>
<Implies>    ::= "imp" <Expression> <Expression>

(<Identifier> is implemented as an IdentifierTerminal object).

I've used Irony to parse expressions before but for some reason, I cannot get it to work. When I type the expression and P Q it seems to be identifying "and" as an Identifier terminal, not part of the And nonterminal. I may be doing something obvious but I simply can't figure it out. Here is the language class I extended:

class LogicPrefix : Grammar
{
    public LogicPrefix()
        : base(false)
    {
        NonTerminal Expression = new NonTerminal("expression");
        NonTerminal Implies = new NonTerminal("implies");
        NonTerminal And = new NonTerminal("and");
        NonTerminal Or = new NonTerminal("or");
        NonTerminal Not = new NonTerminal("not");
        Terminal Identifier = new IdentifierTerminal("identifier");
        Root = Expression;

        Expression.Rule = And | Or | Not | Identifier;

        Not.Rule = "not" + Expression;
        Implies.Rule = "imp" + Expression + Expression;
        And.Rule = "and" + Expression + Expression;
        Or.Rule = "or" + Expression + Expression;

    }
}

And here is my driver class:

class Program
{
    static void Main(string[] args)
    {
        LogicPrefix grammar = new LogicPrefix();
        Parser p = new Parser(grammar);
        ParseTree pt = p.Parse("and P Q");
        //pt has thrown an error flag.
    }
}

Please let me know if I'm doing something wrong, I'd love some advice on this.


回答1:


Your identifier lexing seems to allow your other terminals to be lexed as identifiers because by definition IdentifierTerminal recognizes anything that "starts with an underscore or letter and contains only letters, numbers, and underscores" (source). This means that when your program reads the and, it can read it as the identifier and or the keyword and.

It looks to me like you can fix this by declaring your operators to be punctuation with the following line:

MarkPunctuation("imp", "and", "or", "not")


来源:https://stackoverflow.com/questions/13282917/implementing-a-prefix-notation-expression-parser-using-irony

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!