Basic test works... have 5 shift/reduce conflicts that I'm not sure how to resolve.
authorBenjamin Smedberg <benjamin@smedbergs.us>
Tue, 03 Jun 2008 11:48:28 -0400
changeset 1 b517a34167cf
parent 0 bcee2804dcd5
child 2 0e9e86907aa6
push id2
push userbsmedberg@mozilla.com
push dateTue, 03 Jun 2008 15:48:43 +0000
Basic test works... have 5 shift/reduce conflicts that I'm not sure how to resolve.
xpidl.py
--- a/xpidl.py
+++ b/xpidl.py
@@ -24,16 +24,17 @@ keywords = {
     'array': 'ARRAY',
     'size_is': 'SIZE_IS',
     'retval': 'RETVAL',
     'uuid_is':  'UUID_IS',
     'noscript': 'NOSCRIPT',
     'notxpcom': 'NOTXPCOM',
     'scriptable': 'SCRIPTABLE',
     'attribute': 'ATTRIBUTE',
+    'readonly': 'READONLY',
     'function': 'FUNCTION',
     'object': 'OBJECT',
     'native': 'NATIVE'
 }
 
 tokens = [
 #    'COMMENT',
     'IDENTIFIER',
@@ -56,36 +57,39 @@ tokens = [
 tokens.extend(keywords.values())
 
 def t_COMMENT(t):
     r'/\*(?s).*?\*/'
     t.lexer.lineno += t.value.count('\n')
     # t.value = t.value[2:-2]
     # return t
 
-t_IDENTIFIER = r'unsigned\ long\ long|unsigned\ short|unsigned\ long|long\ long|[A-Za-z][A-Za-z_0-9]*'
+hexchar = r'[a-fA-F0-9]'
+def t_IID(t):
+    return t
+t_IID.__doc__ = r'%(c)s{8}-%(c)s{4}-%(c)s{4}-%(c)s{4}-%(c)s{12}' % {'c': hexchar}
+
+def t_IDENTIFIER(t):
+    r'unsigned\ long\ long|unsigned\ short|unsigned\ long|long\ long|[A-Za-z][A-Za-z_0-9]*'
+    t.type = keywords.get(t.value, 'IDENTIFIER')
+    return t
 
 def t_LCDATA(t):
     r'%\{C\+\+(?s).*?%\}'
     t.type = 'CDATA'
     t.value = t.value[5:-2]
     t.lexer.lineno += t.value.count('\n')
     return t
 
 def t_INCLUDE(t):
     r'\#include[ \t]+"[^"\n]+"'
     inc, value, end = t.value.split('"')
     t.value = value
     return t
 
-hexchar = r'[a-fA-F0-9]'
-def t_IID(t):
-    return t
-t_IID.__doc__ = r'%(c)s{8}-%(c)s{4}-%(c)s{4}-%(c)s{4}-%(c)s{12}' % {'c': hexchar}
-
 t_DQUOTE = r'"'
 t_LPAREN = r'\('
 t_RPAREN = r'\)'
 
 t_LBRACE = r'\{'
 t_RBRACE = r'\}'
 t_LBRACKET = r'\['
 t_RBRACKET = r'\]'
@@ -99,28 +103,27 @@ def t_newline(t):
 def t_ws(t):
   r'[ \t]+'
   pass
 
 lex.lex(debug=True)
 
 data = r"""
 #include "nsISupports.idl"
-"""
 
-# %{C++
-# typedef foo bar;
-# %}
+%{C++
+typedef foo bar;
+%}
 
-# [scriptable,uuid(E7669CB5-020C-4B1E-8BB3-C75A14AD84DE)]
-# interface nsIFoo
-# {
-#   attribute unsigned long value;
-# };
-# """
+[scriptable,uuid(E7669CB5-020C-4B1E-8BB3-C75A14AD84DE)]
+interface nsIFoo
+{
+  attribute unsigned long value;
+};
+"""
 
 lex.input(data)
 
 def p_idlfile(p):
     """idlfile : includes cdata interfaces"""
     p[0] = {'includes': p[1],
             'cdata': p[2],
             'interfaces': p[3]}
@@ -135,55 +138,88 @@ def p_includes_start(p):
 
 def p_includes_continue(p):
     """includes : INCLUDE includes"""
     p[0] = list(p[2])
     p[0].insert(0, p[1])
 
 def p_cdata_start(p):
     """cdata : empty"""
-    p[0] = []
+    p[0] = ""
 
 def p_cdata_continue(p):
     """cdata : CDATA cdata"""
-    p[0] = list(p[2])
-    p[0].insert(p[1])
+    p[0] = p[1] + p[2]
 
 def p_interfaces_start(p):
     """interfaces : empty"""
     p[0] = []
 
 def p_interfaces_continue(p):
     """interfaces : interface cdata interfaces"""
     p[0] = list(p[2])
     p[0].insert(0, {'interface': p[1],
                     'cdata': p[2]})
 
 def p_interface(p):
-    """interface : ifaceatts INTERFACE IDENTIFIER ifacebase
-                   LBRACE members RBRACE SEMICOLON"""
+    """interface : ifaceatts INTERFACE IDENTIFIER ifacebase LBRACE members RBRACE SEMICOLON"""
     p[0] = {'name': p[3],
             'atts': p[1],
-            'members': p[5]}
+            'members': p[6]}
 
 def p_ifaceatts(p):
     """ifaceatts : LBRACKET ifaceattlist RBRACKET
+                 | LBRACKET RBRACKET
                  | empty"""
-    if len(p):
+    if len(p) == 4:
         p[0] = p[2]
     else:
         p[0] = []
 
-def p_ifaceattlist(p):
-    """ifaceattlist : 
+def p_ifaceattlist_start(p):
+    """ifaceattlist : ifaceatt"""
+    p[0] = [p[1]]
+
+def p_ifaceattlist_continue(p):
+    """ifaceattlist : ifaceatt COMMA ifaceattlist"""
+    p[0] = list(p[3])
+    p[0].insert(0, p[1])
+
+def p_ifaceatt_uuid(p):
+    """ifaceatt : UUID LPAREN IID RPAREN"""
+    p[0] = {'name': 'uuid',
+            'value': p[3]}
+
+def p_ifacatt_scriptable(p):
+    """ifaceatt : SCRIPTABLE"""
+    p[0] = {'name': 'scriptable'}
 
 def p_ifacebase(p):
     """ifacebase : empty
                  | COLON IDENTIFIER"""
     if len(p) == 3:
         p[0] = p[2]
 
-def p_
+def p_members_start(p):
+    """members : empty"""
+    p[0] = []
+
+def p_members_continue(p):
+    """members : member members"""
+    p[0] = list(p[2])
+    p[0].insert(0, p[1])
+
+def p_member_att(p):
+    """member : optreadonly ATTRIBUTE IDENTIFIER IDENTIFIER SEMICOLON"""
+    p[0] = {'kind': 'attribute',
+            'readonly': p[1],
+            'type': p[3],
+            'name': p[4]}
+
+def p_optreadonly(p):
+    """optreadonly : READONLY
+                   | empty"""
+    p[0] = p[1] == 'READONLY'
 
 yacc.yacc()
 
-r = yacc.parse(lexer=lex, input=data, debug=True)
+r = yacc.parse(lexer=lex, debug=True)
 print r