summaryrefslogtreecommitdiffstats
path: root/util/qlalr/examples/qparser
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2009-03-23 09:34:13 (GMT)
committerSimon Hausmann <simon.hausmann@nokia.com>2009-03-23 09:34:13 (GMT)
commit67ad0519fd165acee4a4d2a94fa502e9e4847bd0 (patch)
tree1dbf50b3dff8d5ca7e9344733968c72704eb15ff /util/qlalr/examples/qparser
downloadQt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.zip
Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.gz
Qt-67ad0519fd165acee4a4d2a94fa502e9e4847bd0.tar.bz2
Long live Qt!
Diffstat (limited to 'util/qlalr/examples/qparser')
-rw-r--r--util/qlalr/examples/qparser/COMPILE3
-rw-r--r--util/qlalr/examples/qparser/calc.g93
-rw-r--r--util/qlalr/examples/qparser/calc.l20
-rw-r--r--util/qlalr/examples/qparser/qparser.cpp3
-rw-r--r--util/qlalr/examples/qparser/qparser.h111
-rw-r--r--util/qlalr/examples/qparser/qparser.pro4
6 files changed, 234 insertions, 0 deletions
diff --git a/util/qlalr/examples/qparser/COMPILE b/util/qlalr/examples/qparser/COMPILE
new file mode 100644
index 0000000..4aad300
--- /dev/null
+++ b/util/qlalr/examples/qparser/COMPILE
@@ -0,0 +1,3 @@
+qlalr calc.g
+qmake
+make
diff --git a/util/qlalr/examples/qparser/calc.g b/util/qlalr/examples/qparser/calc.g
new file mode 100644
index 0000000..24371d4
--- /dev/null
+++ b/util/qlalr/examples/qparser/calc.g
@@ -0,0 +1,93 @@
+
+%parser calc_grammar
+%decl calc_parser.h
+%impl calc_parser.cpp
+
+%token_prefix Token_
+%token number
+%token lparen
+%token rparen
+%token plus
+%token minus
+
+%start Goal
+
+/:
+#ifndef CALC_PARSER_H
+#define CALC_PARSER_H
+
+#include "qparser.h"
+#include "calc_grammar_p.h"
+
+class CalcParser: public QParser<CalcParser, $table>
+{
+public:
+ int nextToken();
+ void consumeRule(int ruleno);
+};
+
+#endif // CALC_PARSER_H
+:/
+
+
+
+
+
+/.
+#include "calc_parser.h"
+
+#include <QtDebug>
+#include <cstdlib>
+
+void CalcParser::consumeRule(int ruleno)
+ {
+ switch (ruleno) {
+./
+
+Goal: Expression ;
+/.
+case $rule_number:
+ qDebug() << "value:" << sym(1);
+ break;
+./
+
+PrimaryExpression: number ;
+PrimaryExpression: lparen Expression rparen ;
+/.
+case $rule_number:
+ sym(1) = sym (2);
+ break;
+./
+
+Expression: PrimaryExpression ;
+
+Expression: Expression plus PrimaryExpression;
+/.
+case $rule_number:
+ sym(1) += sym (3);
+ break;
+./
+
+Expression: Expression minus PrimaryExpression;
+/.
+case $rule_number:
+ sym(1) -= sym (3);
+ break;
+./
+
+
+
+/.
+ } // switch
+}
+
+#include <cstdio>
+
+int main()
+{
+ CalcParser p;
+
+ if (p.parse())
+ printf("ok\n");
+}
+./
diff --git a/util/qlalr/examples/qparser/calc.l b/util/qlalr/examples/qparser/calc.l
new file mode 100644
index 0000000..95181d5
--- /dev/null
+++ b/util/qlalr/examples/qparser/calc.l
@@ -0,0 +1,20 @@
+
+%option noyywrap
+
+%{
+#include "calc_parser.h"
+#include <cstdlib>
+
+#define YY_DECL int CalcParser::nextToken()
+%}
+
+%%
+
+[ \t\n] { /* eat me */ }
+[0-9]+ { sym(1) = atoi (yytext); return Token_number; }
+"(" { return Token_lparen; }
+")" { return Token_rparen; }
+"+" { return Token_plus; }
+"-" { return Token_minus; }
+
+%%
diff --git a/util/qlalr/examples/qparser/qparser.cpp b/util/qlalr/examples/qparser/qparser.cpp
new file mode 100644
index 0000000..5a18ee2
--- /dev/null
+++ b/util/qlalr/examples/qparser/qparser.cpp
@@ -0,0 +1,3 @@
+
+#include "qparser.h"
+
diff --git a/util/qlalr/examples/qparser/qparser.h b/util/qlalr/examples/qparser/qparser.h
new file mode 100644
index 0000000..e3ff61d
--- /dev/null
+++ b/util/qlalr/examples/qparser/qparser.h
@@ -0,0 +1,111 @@
+#ifndef QPARSER_H
+#define QPARSER_H
+
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QVarLengthArray>
+
+template <typename _Parser, typename _Table, typename _Value = int>
+class QParser: protected _Table
+{
+public:
+ QParser();
+ ~QParser();
+
+ bool parse();
+
+ inline _Value &sym(int index);
+
+private:
+ inline int nextToken()
+ {
+ return static_cast<_Parser*> (this)->nextToken();
+ }
+
+ inline void consumeRule(int rule)
+ {
+ static_cast<_Parser*> (this)->consumeRule(rule);
+ }
+
+ enum { DefaultStackSize = 128 };
+
+ struct Data: public QSharedData
+ {
+ Data(): stackSize (DefaultStackSize), tos (0) {}
+
+ QVarLengthArray<int, DefaultStackSize> stateStack;
+ QVarLengthArray<_Value, DefaultStackSize> parseStack;
+ int stackSize;
+ int tos;
+
+ void reallocateStack() {
+ stackSize <<= 1;
+ stateStack.resize(stackSize);
+ parseStack.resize(stackSize);
+ }
+ };
+
+ QSharedDataPointer<Data> d;
+};
+
+template <typename _Parser, typename _Table, typename _Value>
+inline _Value &QParser<_Parser, _Table, _Value>::sym(int n)
+{
+ return d->parseStack [d->tos + n - 1];
+}
+
+template <typename _Parser, typename _Table, typename _Value>
+QParser<_Parser, _Table, _Value>::QParser():
+ d(new Data())
+{
+}
+
+template <typename _Parser, typename _Table, typename _Value>
+QParser<_Parser, _Table, _Value>::~QParser()
+{
+}
+
+template <typename _Parser, typename _Table, typename _Value>
+bool QParser<_Parser, _Table, _Value>::parse()
+{
+ const int INITIAL_STATE = 0;
+
+ d->tos = 0;
+ d->reallocateStack();
+
+ int act = d->stateStack[++d->tos] = INITIAL_STATE;
+ int token = -1;
+
+ forever {
+ if (token == -1 && - _Table::TERMINAL_COUNT != _Table::action_index[act])
+ token = nextToken();
+
+ act = _Table::t_action(act, token);
+
+ if (d->stateStack[d->tos] == _Table::ACCEPT_STATE)
+ return true;
+
+ else if (act > 0) {
+ if (++d->tos == d->stackSize)
+ d->reallocateStack();
+
+ d->parseStack[d->tos] = d->parseStack[d->tos - 1];
+ d->stateStack[d->tos] = act;
+ token = -1;
+ }
+
+ else if (act < 0) {
+ int r = - act - 1;
+ d->tos -= _Table::rhs[r];
+ act = d->stateStack[d->tos++];
+ consumeRule(r);
+ act = d->stateStack[d->tos] = _Table::nt_action(act, _Table::lhs[r] - _Table::TERMINAL_COUNT);
+ }
+
+ else break;
+ }
+
+ return false;
+}
+
+
+#endif // QPARSER_H
diff --git a/util/qlalr/examples/qparser/qparser.pro b/util/qlalr/examples/qparser/qparser.pro
new file mode 100644
index 0000000..938e336
--- /dev/null
+++ b/util/qlalr/examples/qparser/qparser.pro
@@ -0,0 +1,4 @@
+QT = core
+HEADERS += calc_grammar_p.h calc_parser.h qparser.h
+SOURCES += calc_grammar.cpp calc_parser.cpp qparser.cpp
+LEXSOURCES += calc.l