+++ /dev/null
-#!/usr/bin/python
-
-import sys
-
-lines = sys.stdin.read().rstrip('\n').split('\n')
-
-def data(line):
- name = line[0].replace('&', 'Ampersand').replace('^', 'Carrot').replace('=', 'Equal').replace('!', 'Exclamation').replace('-', 'Hyphen').replace('<', 'Left').replace('%', 'Percent').replace('.', 'Period').replace('|', 'Pipe').replace('+', 'Plus').replace('>', 'Right').replace('/', 'Slash').replace('*', 'Star').replace('~', 'Tilde')
- text = line[0].lower()
- word = text[0].isalpha()
- prefix = None if line[1] == '-' else line[1]
- assign = None if len(line) < 3 or line[2] != 'A' else '' if len(line) < 4 else line[3]
- infix = None if len(line) < 3 or line[2] != 'R' else line[3]
- precedence = line[4] if infix != None and len(line) > 4 else None
- postfix = infix if infix != None and precedence == None else None
- if postfix != None:
- infix = None
- return name, text, word, prefix, assign, infix, precedence, postfix
-
-def express(expression, type, args, call):
- print 'struct CYExpression%(expression)s :' % locals()
- print ' CYExpression%(type)s' % locals()
- print '{'
- print ' CYExpression%(expression)s(%(args)s) :' % locals()
- print ' CYExpression%(type)s(%(call)s)' % locals()
- print ' {'
- print ' }'
- print '};'
- print
-
-for line in lines:
- line = line.split()
- name, text, word, prefix, assign, infix, precedence, postfix = data(line)
-
- print 'struct CYToken%(name)s :' % locals()
- if prefix != None:
- print ' CYTokenPrefix,'
- if infix != None:
- print ' CYTokenInfix,'
- if postfix != None:
- print ' CYTokenPostfix,'
- if assign != None:
- print ' CYTokenAssignment,'
- if word:
- print ' CYTokenWord,'
- print ' virtual CYToken'
- print '{'
- print ' virtual const char *Text() const {'
- print ' return "%(text)s";' % locals()
- print ' }'
- if precedence != None or prefix != None or assign != None or infix != None:
- print
- if precedence != None:
- print ' virtual unsigned Precedence() const {'
- print ' return %(precedence)s;' % locals()
- print ' }'
- print
- if prefix != None:
- print ' virtual CYExpression *PrefixExpression(apr_pool_t *pool, CYExpression *rhs) const;'
- if infix != None:
- print ' virtual CYExpression *InfixExpression(apr_pool_t *pool, CYExpression *lhs, CYExpression *rhs) const;'
- if postfix != None:
- print ' virtual CYExpression *PostfixExpression(apr_pool_t *pool, CYExpression *lhs) const;'
- if assign != None:
- print ' virtual CYExpression *AssignmentExpression(apr_pool_t *pool, CYExpression *lhs, CYExpression *rhs) const;'
- print '};'
- print
- if prefix != None:
- express(prefix, 'Prefix', 'CYExpression *rhs', 'rhs')
- if infix != None:
- express(infix, 'Infix', 'CYExpression *lhs, CYExpression *rhs', 'lhs, rhs')
- if postfix != None:
- express(postfix, 'Postfix', 'CYExpression *lhs', 'lhs')
- if assign != None:
- express('Assign' + assign, 'Assignment', 'CYExpression *lhs, CYExpression *rhs', 'lhs, rhs')
-
-for line in lines:
- line = line.split()
- name, text, word, prefix, assign, infix, precedence, postfix = data(line)
-
- if prefix != None:
- print 'CYExpression *CYToken%(name)s::PrefixExpression(apr_pool_t *pool, CYExpression *rhs) const {' % locals()
- print ' return new(pool) CYExpression%(prefix)s(rhs);' % locals()
- print '}'
- print
- if infix != None:
- print 'CYExpression *CYToken%(name)s::InfixExpression(apr_pool_t *pool, CYExpression *lhs, CYExpression *rhs) const {' % locals()
- print ' return new(pool) CYExpression%(infix)s(lhs, rhs);' % locals()
- print '}'
- print
- if postfix != None:
- print 'CYExpression *CYToken%(name)s::PostfixExpression(apr_pool_t *pool, CYExpression *rhs) const {' % locals()
- print ' return new(pool) CYExpression%(postfix)s(rhs);' % locals()
- print '}'
- print
- if assign != None:
- print 'CYExpression *CYToken%(name)s::AssignmentExpression(apr_pool_t *pool, CYExpression *lhs, CYExpression *rhs) const {' % locals()
- print ' return new(pool) CYExpressionAssign%(assign)s(lhs, rhs);' % locals()
- print '}'
- print
--- /dev/null
+CYToken_("&", Ampersand, AddressOf, Infix, , CYTokenInfix_(5, BitwiseAnd))
+CYToken_("&&", AmpersandAmpersand, , Infix, , CYTokenInfix_(8, LogicalAnd))
+CYToken_("&=", AmpersandEqual, , Assign, , CYTokenAssign_(BitwiseAnd))
+CYToken_("^", Carrot, , Infix, , CYTokenInfix_(6, BitwiseXOr))
+CYToken_("^=", CarrotEqual, , Assign, , CYTokenAssign_(BitwiseXOr))
+CYToken_("=", Equal, , Assign, , CYTokenAssign_())
+CYToken_("==", EqualEqual, , Infix, , CYTokenInfix_(4, Equal))
+CYToken_("===", EqualEqualEqual, , Infix, , CYTokenInfix_(4, Identical))
+CYToken_("!", Exclamation, LogicalNot, )
+CYToken_("!=", ExclamationEqual, , Infix, , CYTokenInfix_(4, NotEqual))
+CYToken_("!==", ExclamationEqualEqual, , Infix, , CYTokenInfix_(4, NotIdentical))
+CYToken_("-", Hyphen, Negate, Infix, , CYTokenInfix_(1, Subtract) CYTokenPrefix_(Negate))
+CYToken_("-=", HyphenEqual, Assign, , CYTokenAssign_(Subtract))
+CYToken_("--", HyphenHyphen, Postfix, CYTokenEx_(Prefix), CYTokenPostfix_(Decrement))
+CYToken_("->", HyphenRight, Access, , )
+CYToken_("<", Left, Infix, , CYTokenInfix_(3, LessThan))
+CYToken_("<=", LeftEqual, Infix, , CYTokenInfix_(3, LessThanOrEqual))
+CYToken_("<<", LeftLeft, Infix, , CYTokenInfix_(2, LeftShift))
+CYToken_("<<=", LeftLeftEqual, Assign, , CYTokenAssign_(LeftShift))
+CYToken_("%", Percent, Infix, , CYTokenInfix_(0, Modulus))
+CYToken_("%=", PercentEqual, Assign, , CYTokenAssign_(Modulus))
+CYToken_(".", Period, Access, , )
+CYToken_("|", Pipe, Infix, , CYTokenInfix_(7, BitwiseOr))
+CYToken_("|=", PipeEqual, Assign, , CYTokenAssign_(BitwiseOr))
+CYToken_("||", PipePipe, Infix, , CYTokenInfix_(9, LogicalOr))
+CYToken_("+", Plus, Infix, , CYTokenInfix_(1, Add))
+CYToken_("+=", PlusEqual, Assign, , CYTokenAssign_(Add))
+CYToken_("++", PlusPlus, Postfix, CYTokenEx_(Prefix), CYTokenPostfix_(Increment))
+CYToken_(">", Right, Infix, , CYTokenInfix_(3, GreaterThan))
+CYToken_(">=", RightEqual, Infix, , CYTokenInfix_(3, GreaterThanOrEqual))
+CYToken_(">>", RightRight, Infix, , CYTokenInfix_(2, SignedRightShift))
+CYToken_(">>=", RightRightEqual, Assign, , CYTokenAssign_(SignedRightShift))
+CYToken_(">>>", RightRightRight, Infix, , CYTokenInfix_(2, UnsignedRightShift))
+CYToken_(">>>=", RightRightRightEqual, Assign, , CYTokenAssign_(UnsignedRightShift))
+CYToken_("/", Slash, Infix, , CYTokenInfix_(0, Divide))
+CYToken_("/=", SlashEqual, Assign, , CYTokenAssign_(Divide))
+CYToken_("*", Star, Infix, CYTokenEx_(Prefix), CYTokenInfix_(0, Multiply) CYTokenPrefix_(Indirect))
+CYToken_("*=", StarEqual, Assign, , CYTokenAssign_(Multiply))
+CYToken_("~", Tilde, , CYTokenEx_(Prefix), CYTokenPrefix_(BitwiseNot))
--- /dev/null
+struct CYExpression {
+};
+
+struct CYToken {
+ virtual const char *Text() const = 0;
+};
+
+struct CYTokenPrefix :
+ virtual CYToken
+{
+};
+
+struct CYTokenInfix :
+ virtual CYToken
+{
+ virtual unsigned Precedence() const = 0;
+};
+
+struct CYTokenPostfix :
+ virtual CYToken
+{
+};
+
+struct CYTokenAssignment :
+ virtual CYToken
+{
+};
+
+struct CYTokenAccess :
+ virtual CYToken
+{
+};
+
+struct CYTokenLiteral :
+ CYExpression,
+ virtual CYToken
+{
+};
+
+struct CYTokenString :
+ CYTokenLiteral
+{
+};
+
+struct CYTokenNumber :
+ CYTokenLiteral
+{
+};
+
+struct CYTokenWord :
+ virtual CYToken
+{
+};
+
+struct CYTokenIdentifier :
+ CYExpression,
+ CYTokenWord
+{
+ const char *word_;
+
+ virtual const char *Text() const {
+ return word_;
+ }
+};
+
+struct CYTokenColon :
+ CYToken
+{
+};
+
+struct CYTokenComma :
+ CYToken
+{
+};
+
+struct CYTokenSemi :
+ CYToken
+{
+};
+
+struct CYTokenQuestion :
+ CYToken
+{
+};
+
+std::set<const char *, CStringMapLess> OperatorWords_;
+
+struct CYParser {
+ FILE *fin_;
+ FILE *fout_;
+
+ size_t capacity_;
+ char *data_;
+
+ size_t offset_;
+ size_t size_;
+
+ CYPool pool_;
+
+ CYParser(FILE *fin, FILE *fout) :
+ fin_(fin),
+ fout_(fout),
+ capacity_(1024),
+ data_(reinterpret_cast<char *>(malloc(capacity_))),
+ offset_(0),
+ size_(0)
+ {
+ }
+
+ ~CYParser() {
+ // XXX: this will not deconstruct in constructor failures
+ free(data_);
+ }
+
+ bool ReadLine(const char *prompt) {
+ offset_ = 0;
+ data_[capacity_ - 1] = ~'\0';
+
+ start:
+ if (fout_ != NULL) {
+ fputs(prompt, fout_);
+ fputs(" ", fout_);
+ fflush(fout_);
+ }
+
+ if (fgets(data_, capacity_, fin_) == NULL)
+ return false;
+
+ check:
+ if (data_[capacity_ - 1] != '\0') {
+ size_ = strlen(data_);
+ if (size_ == 0)
+ goto start;
+ if (data_[size_ - 1] == '\n') {
+ --size_;
+ goto newline;
+ }
+ } else if (data_[capacity_ - 2] == '\n') {
+ size_ = capacity_ - 2;
+ newline:
+ data_[size_] = '\0';
+ } else {
+ size_t capacity(capacity_ * 2);
+ char *data(reinterpret_cast<char *>(realloc(data_, capacity)));
+ _assert(data != NULL);
+ data_ = data;
+ size_ = capacity_ - 1;
+ capacity_ = capacity;
+ fgets(data_ + size_, capacity_ - size_, fin_);
+ goto check;
+ }
+
+ return true;
+ }
+
+ _finline void ScanRange(const CYRange &range) {
+ while (range[data_[offset_]])
+ ++offset_;
+ }
+
+ CYToken *ParseToken(const char *prompt) {
+ char next;
+
+ do {
+ if (offset_ == size_ && (prompt == NULL || !ReadLine(prompt)))
+ return false;
+ next = data_[offset_++];
+ } while (next == ' ' || next == '\t');
+
+ CYTokenType type;
+ size_t index(offset_ - 1);
+
+ if (WordStartRange_[next]) {
+ ScanRange(WordEndRange_);
+ type = CYTokenWord;
+ } else if (next == '.') {
+ char after(data_[offset_]);
+ if (after >= '0' && after <= '9')
+ goto number;
+ goto punctuation;
+ } else if (next >= '0' && next <= '9') {
+ number:
+ ScanRange(NumberRange_);
+ type = CYTokenLiteral;
+ } else if (PunctuationRange_[next]) {
+ punctuation:
+ ScanRange(PunctuationRange_);
+ type = CYTokenPunctuation;
+ } else if (next == '"' || next == '\'') {
+ for (;;) {
+ char after(data_[offset_++]);
+ if (after == '\\') {
+ after = data_[offset_++];
+ _assert(after != '\0');
+ if (after == 'u') {
+ offset_ += 4;
+ _assert(offset_ < size_);
+ }
+ } else if (after == next)
+ break;
+ }
+
+ type = CYTokenLiteral;
+ } else if (next == '(' || next == '{' || next == '[') {
+ type = CYTokenOpen;
+ } else if (next == ')' || next == '}' || next == ']') {
+ type = CYTokenClose;
+ } else if (next == ';') {
+ type = CYTokenSemiColon;
+ } else {
+ printf(":( %u\n", next);
+ _assert(false);
+ }
+
+ char *value(pool_(data_ + index, offset_ - index));
+
+ if (type == CYTokenWord && OperatorWords_.find(value) != OperatorWords_.end())
+ type = CYTokenPunctuation;
+
+ CYToken *token(new(pool_) CYToken());
+ token->type_ = type;
+ token->value_ = value;
+ token->next_ = token;
+ token->prev_ = &token->next_;
+ return token;
+ }
+
+ CYToken *ParseExpression(const char *prompt) {
+ CYToken *token(ParseToken(prompt));
+ return token;
+ }
+};
--- /dev/null
+#!/usr/bin/python
+
+import sys
+
+lines = sys.stdin.read().rstrip('\n').split('\n')
+
+def data(line):
+ name = line[0].replace('&', 'Ampersand').replace('^', 'Carrot').replace('=', 'Equal').replace('!', 'Exclamation').replace('-', 'Hyphen').replace('<', 'Left').replace('%', 'Percent').replace('.', 'Period').replace('|', 'Pipe').replace('+', 'Plus').replace('>', 'Right').replace('/', 'Slash').replace('*', 'Star').replace('~', 'Tilde')
+ text = line[0].lower()
+ word = text[0].isalpha()
+ prefix = None if line[1] == '-' else line[1]
+ assign = None if len(line) < 3 or line[2] != 'A' else '' if len(line) < 4 else line[3]
+ infix = None if len(line) < 3 or line[2] != 'R' else line[3]
+ precedence = line[4] if infix != None and len(line) > 4 else None
+ postfix = infix if infix != None and precedence == None else None
+ if postfix != None:
+ infix = None
+ return name, text, word, prefix, assign, infix, precedence, postfix
+
+def express(expression, type, args, call):
+ print 'struct CYExpression%(expression)s :' % locals()
+ print ' CYExpression%(type)s' % locals()
+ print '{'
+ print ' CYExpression%(expression)s(%(args)s) :' % locals()
+ print ' CYExpression%(type)s(%(call)s)' % locals()
+ print ' {'
+ print ' }'
+ print '};'
+ print
+
+for line in lines:
+ line = line.split()
+ name, text, word, prefix, assign, infix, precedence, postfix = data(line)
+
+ print 'struct CYToken%(name)s :' % locals()
+ if prefix != None:
+ print ' CYTokenPrefix,'
+ if infix != None:
+ print ' CYTokenInfix,'
+ if postfix != None:
+ print ' CYTokenPostfix,'
+ if assign != None:
+ print ' CYTokenAssignment,'
+ if word:
+ print ' CYTokenWord,'
+ print ' virtual CYToken'
+ print '{'
+ print ' virtual const char *Text() const {'
+ print ' return "%(text)s";' % locals()
+ print ' }'
+ if precedence != None or prefix != None or assign != None or infix != None:
+ print
+ if precedence != None:
+ print ' virtual unsigned Precedence() const {'
+ print ' return %(precedence)s;' % locals()
+ print ' }'
+ print
+ if prefix != None:
+ print ' virtual CYExpression *PrefixExpression(apr_pool_t *pool, CYExpression *rhs) const;'
+ if infix != None:
+ print ' virtual CYExpression *InfixExpression(apr_pool_t *pool, CYExpression *lhs, CYExpression *rhs) const;'
+ if postfix != None:
+ print ' virtual CYExpression *PostfixExpression(apr_pool_t *pool, CYExpression *lhs) const;'
+ if assign != None:
+ print ' virtual CYExpression *AssignmentExpression(apr_pool_t *pool, CYExpression *lhs, CYExpression *rhs) const;'
+ print '};'
+ print
+ if prefix != None:
+ express(prefix, 'Prefix', 'CYExpression *rhs', 'rhs')
+ if infix != None:
+ express(infix, 'Infix', 'CYExpression *lhs, CYExpression *rhs', 'lhs, rhs')
+ if postfix != None:
+ express(postfix, 'Postfix', 'CYExpression *lhs', 'lhs')
+ if assign != None:
+ express('Assign' + assign, 'Assignment', 'CYExpression *lhs, CYExpression *rhs', 'lhs, rhs')
+
+for line in lines:
+ line = line.split()
+ name, text, word, prefix, assign, infix, precedence, postfix = data(line)
+
+ if prefix != None:
+ print 'CYExpression *CYToken%(name)s::PrefixExpression(apr_pool_t *pool, CYExpression *rhs) const {' % locals()
+ print ' return new(pool) CYExpression%(prefix)s(rhs);' % locals()
+ print '}'
+ print
+ if infix != None:
+ print 'CYExpression *CYToken%(name)s::InfixExpression(apr_pool_t *pool, CYExpression *lhs, CYExpression *rhs) const {' % locals()
+ print ' return new(pool) CYExpression%(infix)s(lhs, rhs);' % locals()
+ print '}'
+ print
+ if postfix != None:
+ print 'CYExpression *CYToken%(name)s::PostfixExpression(apr_pool_t *pool, CYExpression *rhs) const {' % locals()
+ print ' return new(pool) CYExpression%(postfix)s(rhs);' % locals()
+ print '}'
+ print
+ if assign != None:
+ print 'CYExpression *CYToken%(name)s::AssignmentExpression(apr_pool_t *pool, CYExpression *lhs, CYExpression *rhs) const {' % locals()
+ print ' return new(pool) CYExpressionAssign%(assign)s(lhs, rhs);' % locals()
+ print '}'
+ print
--- /dev/null
+#!/usr/bin/python
+
+import sys
+
+lines = sys.stdin.read().rstrip('\n').split('\n')
+
+def data(line):
+ name = line[0].replace('&', 'Ampersand').replace('^', 'Carrot').replace('=', 'Equal').replace('!', 'Exclamation').replace('-', 'Hyphen').replace('<', 'Left').replace('%', 'Percent').replace('.', 'Period').replace('|', 'Pipe').replace('+', 'Plus').replace('>', 'Right').replace('/', 'Slash').replace('*', 'Star').replace('~', 'Tilde')
+ text = line[0].lower()
+ word = text[0].isalpha()
+ prefix = None if line[1] == '-' else line[1]
+ assign = None if len(line) < 3 or line[2] != 'A' else '' if len(line) < 4 else line[3]
+ infix = None if len(line) < 3 or line[2] != 'R' else line[3]
+ precedence = line[4] if infix != None and len(line) > 4 else None
+ postfix = infix if infix != None and precedence == None else None
+ if postfix != None:
+ infix = None
+ return name, text, word, prefix, assign, infix, precedence, postfix
+
+for line in lines:
+ line = line.split()
+ name, text, word, prefix, assign, infix, precedence, postfix = data(line)
+ print '%%token <CYToken%(name)s> CYToken%(name)s "%(text)s"' % locals()