Boost.Spirit Parser crasht mit Segfault -



  • UltraGram ist klasse, und perfekt für meine Zwecke geeignet. 👍



  • IIIIEEEEHH!!
    UltraGrams Codegenerator produziert Code mit malloc/realloc/free!
    😮 😮 😮 😮 😮 😮 😮 😮 😮 😮

    Ich werde erstmal ein Viertelstündchen heulen. Darf sowas nicht jeden Tag machen.



  • Und was ist das bitte für ein OOP-Modell, in dem Klassen nicht mal ihre eigenen Abhängigkeiten bereitstellen? Jetzt muss ich einen Haufen Header einbinden -.-

    😞 😞



  • Ich habe heute eine sehr wichtige Lektion gelernt. Acuh wenn Ultragram einen schönen Editor hatte, usw.

    War Whalecalf doch so geil und hatte richtiges C++ auf Lager (inkl. Templates, C++-Streams, schön generisch alles, usw.).



  • Und wieder Blödsinn.
    Da wird std und ein anderer Namespace mitten im Header geöffnet...



  • wie wärs einfach, wenn du die Grammatik umformulierst, sodass sie LL ist? das ist nicht so schwer.



  • otze schrieb:

    wie wärs einfach, wenn du die Grammatik umformulierst, sodass sie LL ist? das ist nicht so schwer.

    Na ich weiß nicht, ich will lieber noch einige Dutzend Stunden mit WhaleCalf verbringen 😃

    Ich versuch mich mal mit Umformulierung. Mal sehen, was bei rauskommt.



  • Der Trick ist, dass du das so mformulieren kannst, dass du erst etwas liest, was keine Aussage ist und erst dann ein "and" oder "or" optional folgt.



  • Sone schrieb:

    [...] ich will lieber noch einige Dutzend Stunden mit WhaleCalf verbringen 😃

    👍 ... dann hast wenigstens keine Zeit im Forum zu nerven 😉



  • otze schrieb:

    Der Trick ist, dass du das so mformulieren kannst, dass du erst etwas liest, was keine Aussage ist und erst dann ein "and" oder "or" optional folgt.

    Und die Klammern und NOT. Also praktisch ein Baum:

    NOT (T AND F)
    

    Wird zu

    NOT     //UND SCHLIEßLICH DAS
         /
    BRACED_EXPR  //DANN DAS
       / 
     AND         // DANN DAS
     / \
    T   F        //ZUERST LESEN (Oder Variable >> !Index)
    

    Oder geh ich wieder in die falsche Richtung?



  • das einzige was du verhindern musst, ist dass "Aussage" linksrekursiv ist (das heißt, der Parser darf nicht ohne irgendetwas zu lesen die Ableitung Aussage->Aussage->Aussage->Aussage anwenden können. Schreib die Regeln einfahc so um, dass immer mindestens 1 Zeichen gelesen wird.



  • Bevor ich das jetzt angehe: Ist danach die Syntax die selbe?



  • Also ich hatte nie Probleme mit flex und bison .



  • Ich schaue mir gerade deinen Code an:

    ich würde ja die Variablen als Kleinbuchstaben lassen. Das macht die Sache eindeutig zu parsen (in LL(1))

    Alternative Formulierung für Aussage:

    ( !() ist 0 oder 1 mal)

    Aussage := ("T" | "F" | "(" Aussage ")" | "NOT" Aussage | Variable [Index])
               !( "AND" Aussage | "OR" Aussage )
    


  • otze schrieb:

    Aussage := ("T" | "F" | "(" Aussage ")" | "NOT" Aussage | Variable [Index])
               !( "AND" Aussage | "OR" Aussage )
    

    Teste ich gleich mal.



  • Verdammt Otze... 😞
    Wieso tust du so etwas? Jetzt hab ich NIX gelernt. 😃 🙂
    Einzig und allein gibt es den Fehler, dass

    asdf4

    Als falsch ausgewertet wird. Aber das fix ich selber 🙂

    Ich werde aber auch noch einmal eine Version mit WhaleCalf machen (die API, die das Problem mit unsigned char hatte). Die ist zwar todeshässlich, doch ist es mal eine Erfahrung wert mit todeshässlichen APIs zu arbeiten.



  • In deiner Version, Otze, kann man übrigens "NOT" nach vorne stellen, oder?

    Aussage := !("NOT") ("T" | "F" | "(" Aussage ")" | Variable [Index])
               !( "AND" Aussage | "OR" Aussage )
    


  • ICH HABS (schon seit einer Weile, hab nähmlich bereits nen Installer für mein Programm 😃 )!
    Mit konjunktiver Grammatik im Whilecalf Format:

    algorithm = LR;
    
    terminal _a, _b, _c, _d, _e, _f, _g, _h, _i, _j,
        _k, _l, _m, _n, _o, _p, _q, _r, _s, _t,
        _u, _v, _w, _x, _y, _z;
    
    terminal _0, _1, _2, _3, _4, _5, _6, _7;
    
    terminal _braceOpen, _braceClose;
    
    terminal _equalSign, _Colon;
    
    programm -> _f _u _n _c _t _i _o _n variable assignments _r _e _t _u _r _n expression;
    
    assignments -> assignments assignment | e;
    assignment -> variable _Colon _equalSign expression;
    
    expression -> _t
                | _f
                | expression _a _n _d expression
                | expression _o _r expression
                | _braceOpen expression _braceClose
                | _n _o _t expression
                | variable
                | variable index;
    
    variable -> variable alphabet | e;
    
    index -> _0| _1| _2| _3| _4| _5| _6| _7;
    
    alphabet -> _a | _b | _c | _d | _e | _f | _g | _h |
        _i | _j | _k | _l | _m | _n | _o | _p | _q |
        _r | _s | _t | _u | _v | _w | _x | _y | _z;
    

    Wer will, dem kann ich den Installer zuschicken (für Win7 oder vllt. auch frühere Versionen).



  • Ich hätte mehr Interesse an dem Quellcode. Kann man den wo downloaden? :p



  • out schrieb:

    Ich hätte mehr Interesse an dem Quellcode. Kann man den wo downloaden? :p

    Poste ich gerne hier. Seid aber nicht zu streng mit mir, bin halt noch totaler Anfänger.

    Ich hab zwei getrennte Parser generieren lassen, einmal für Aussage und einmal für Programm.

    main.cxx

    #include "MainWindow.hxx"
    #include "MainWindow.moc.hxx"
    
    int main(int argv, char* argc[])
    {
            QApplication qapp(argv, argc);
    
            MainWindow w;
            w.show();
    
            qapp.exec();
    }
    
    #ifndef MAINWINDOW_HXX_INCLUDED
    #define MAINWINDOW_HXX_INCLUDED
    
    #include <QWidget>
    #include <QMessageBox>
    
    #include <memory>
    
    #include "MainWindow.uic.hxx"
    #include "grammar.h"
    #include "grammar.expression.h"
    
    #include <vector>
    #include <iterator>
    #include <stdexcept>
    
    using std::string;
    using std::vector;
    
    enum class EBNF_T
    {
            expression,
            programm
    };
    
    vector<int> toTerminals(string const& str, EBNF_T ebnf)
    {
            vector<int> rval;
    
            for(char c : str)
            {
                    if(std::isspace(c))
                            continue;
                    else if(c >= 'a' && c <= 'z')
                            rval.push_back(c - 'a');
                    else if(c >= 'A' && c <= 'Z')
                            rval.push_back(c - 'A');
                    else if(c >= '0' && c <= '7')
                            rval.push_back(c - '0' + Grammar::Terminal_z + 1);
                    else if(ebnf == EBNF_T::programm
                        or  (c == '(' or c == ')'))
                            switch(c)
                            {
                                    case ')':
                                            rval.push_back(Grammar::Terminal_braceClose);
                                            break;
                                    case '(':
                                            rval.push_back(Grammar::Terminal_braceOpen);
                                            break;
                                    case ':':
                                            rval.push_back(Grammar::Terminal_Colon);
                                            break;
                                    case '=':
                                            rval.push_back(Grammar::Terminal_equalSign);
                                            break;
                                    default:
                                            return std::vector<int>();
                            }
                    else
                            return std::vector<int>();
            }
    
            return rval;
    }
    
    class MainWindow : public QWidget, public Ui::Form
    {
    Q_OBJECT
    
    public:
    
            MainWindow(QWidget* parent = nullptr):
            QWidget(parent),
            mParser(Grammar::grammar),
            mParserExpr(Grammar_expression::grammar)
            {
                    setupUi(this);
    
                    comboBox->addItem("Programm");
                    comboBox->addItem("Expression");
    
                    connect(pushButton, SIGNAL(clicked()), this, SLOT(parsePressed()));
            }
    
    public slots:
    
            void parsePressed()
            {
                    using namespace Grammar;
    
                    QMessageBox::Icon icon;
                    std::string message;
    
                    auto vec = toTerminals( textEdit->toPlainText().toStdString(), (comboBox->currentIndex() == 1)? EBNF_T::expression : EBNF_T::programm );
                    if(!vec.size())
                    {
                            message = "Invalid character in term!";
                            icon = QMessageBox::Warning;
                    }
                    else
                    {
                            bool valid;
                            if(comboBox->currentIndex() == 0)
                            {
                                    mParser.read(vec);
                                    valid =  mParser.recognize();
                            }
                            else
                            {
                                    mParserExpr.read(vec);
                                    valid =  mParserExpr.recognize();
                            }
    
                            message = (valid ? "Valid term!" : "Invalid term!");
                            icon = (valid ? QMessageBox::Warning : QMessageBox::Information);
                    }
    
                    QMessageBox box(icon, "Parse Information", message.c_str(), QMessageBox::Ok, this);
                    box.exec();
            }
    
    private:
    
            WhaleCalfLRParser mParser;///Der generierte LR-Parser
            WhaleCalfLRParser mParserExpr;///Ein anderer, für Ausdruck allein
    };
    
    #endif // MAINWINDOW_HXX_INCLUDED
    

    Ich hab Qt-Layout Files (+QtDesigner) benutzt, der Quellcode wurde zum Teil (grammar.h, grammar.expression.h) generiert.
    Dazu noch die vom MOC und UIC generierten Header.

    Ich hab jetzt keine Lust Whilecalf zu erklären.

    Ich bin furchtbar im erklären 😃


Anmelden zum Antworten