meta_grammar.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. """
  2. Author: Daniel Riegelhaupt
  3. Date: October 2014
  4. The meta grammar needed by Bruno Barroca's parser to read other grammars.
  5. Based on his data structure
  6. """
  7. #TODO check escape characters in errortext
  8. class Grammar(object):
  9. def __init__(self):
  10. self.tokens = {
  11. #'<token name>' : { 'type': 'token', 'reg': '<token value>' 'errortext': '<human readable error text>'}
  12. "LOWER_CASE": { 'type': 'token', 'reg': r'[a-z_][a-z_0-9]*', 'errortext': 'Lower case characters'},
  13. "UPPER_CASE": { 'type': 'token', 'reg': r'[A-Z_][A-Z_0-9]*', 'errortext': 'Upper case characters'},
  14. "REGEXP": { 'type': 'token', 'reg': r'\'(.|\n)*?[^\\]\'', 'errortext': 'Regular expression'},
  15. "INT": { 'type': 'token', 'reg': r'[0-9]*', 'errortext': 'Integers'},
  16. "IMPLICIT_MOD": { 'type': 'token', 'reg': r'(@Implicit|@Impl)', 'errortext': '@Implicit or @Impl'},
  17. "MESSAGE_MOD": { 'type': 'token', 'reg': r'(@Message|@Msg)', 'errortext': '@Message or @Msg'},
  18. "REMOVE_MOD": { 'type': 'token', 'reg': r'(@Remove|@Rm)', 'errortext': '@Remove or @Rm'},
  19. "TOKENS": { 'type': 'token', 'reg': r'tokens' , 'errortext': 'tokens'},
  20. "KEYWORDS": { 'type': 'token', 'reg': r'keywords', 'errortext': 'keywords'},
  21. "GRAMMAR": { 'type': 'token', 'reg': r'grammar', 'errortext': 'grammar'},
  22. "MAPPER": { 'type': 'token', 'reg': r'mapper', 'errortext': 'mapper'},
  23. "OPER": { 'type': 'token', 'reg': r'[?*+]', 'errortext': '? or * or +'},
  24. "CARD": { 'type': 'token', 'reg': r'#', 'errortext': '#'},
  25. "MINUS": { 'type': 'token', 'reg': r'-', 'errortext': '-'},
  26. "OR": { 'type': 'token', 'reg': r'\|', 'errortext': '|' },
  27. "LPAR": { 'type': 'token', 'reg': r'\(', 'errortext': '(' },
  28. "RPAR": { 'type': 'token', 'reg': r'\)', 'errortext': ')' },
  29. "SEMICOL": { 'type': 'token', 'reg': r';', 'errortext': ';' },
  30. "COMMA": { 'type': 'token', 'reg': r',', 'errortext': ',' },
  31. "LCBR": { 'type': 'token', 'reg': r'\{', 'errortext': '{'},
  32. "RCBR": { 'type': 'token', 'reg': r'\}', 'errortext': '}' },
  33. "LSBR": { 'type': 'token', 'reg': r'\[', 'errortext': '['},
  34. "RSBR": { 'type': 'token', 'reg': r'\]', 'errortext': ']' },
  35. "DOT": { 'type': 'token', 'reg': r'\.', 'errortext': '.'},
  36. "COLON": { 'type': 'token', 'reg': r':', 'errortext': ':'},
  37. "NEWLINE": { 'type': 'token', 'reg': r'(\r?\n[\t ]*)+' , 'errortext': 'New Line'},
  38. "WS": { 'type': 'token', 'reg': r'[\t \f]+' , 'errortext': 'White space'},
  39. "LINE_CONT": { 'type': 'token', r'reg': '\\[\t \f]*\r?\n', 'errortext': 'Line continuation'},
  40. "COMMENT": { 'type': 'token', r'reg': '//[^\n]*', 'errortext': 'Comment'}
  41. }
  42. self.rules = {
  43. 'start': {'type': 'prod', 'body':['.', '@grammar', ['?', '@mapper' ]] , 'errortext': 'Top level start',
  44. 'interleave': ['?','@implicit'] },
  45. 'grammar': {'type': 'prod', 'body': ['.', '$GRAMMAR', '$LCBR', ['*', '@production_rule'], '$RCBR' ],
  46. 'errortext': 'Grammar definition'},
  47. 'production_rule': {'type': 'prod', 'body': ['|', '@rule_definition', '@token_collection' ],
  48. 'errortext': 'Top level production rule definition'},
  49. 'rule_definition': {'type': 'prod', 'body':
  50. ['.', '@rule_name', '$COLON', '@rule_right_hand_side', ['*',['|','@message','@remove']],'$SEMICOL' ],
  51. 'errortext': 'Production rule definition'},
  52. 'rule_name': {'type': 'prod', 'body': ['.' , '$LOWER_CASE'], 'errortext': 'Rule name' },
  53. 'rule_right_hand_side': { 'type': 'prod', 'body': [ '|', '@token_name', '@token_value', '@rule_name',
  54. ['.', '$LPAR', '@rule_right_hand_side', '$RPAR',
  55. ['?', '@cardinality']],
  56. ['.', '@rule_right_hand_side', '$OR', '@rule_right_hand_side'],
  57. ['.', '@rule_right_hand_side', '@rule_right_hand_side'],
  58. ['.', '@rule_right_hand_side', '$OPER' ]],
  59. 'errortext': 'Production rule right hand side'},
  60. 'cardinality': { 'type': 'prod', 'body': ['.', '$CARD', ['?', ['.','$LSBR', ['?', '$MINUS'], '$INT' ,'$RSBR']]],
  61. 'errortext': 'Cardinality'},
  62. 'message': { 'type': 'prod', 'body': ['.', '$MESSAGE_MOD', '@message_value'],
  63. 'errortext': 'Error message'},
  64. 'message_value': { 'type': 'prod', 'body': ['.','$REGEXP'], 'errortext': 'Error message value' },
  65. 'token_collection': { 'type': 'prod', 'body': ['.', '$TOKENS', '$LCBR',
  66. ['*', [ '|', '@token_sub_collection', '@token_definition']],
  67. '$RCBR' ],
  68. 'errortext': 'Top level token definition' },
  69. 'token_sub_collection': { 'type': 'prod', 'body': [ '.', '@token_collection_category', '$COLON',
  70. '@collection_name', '$LCBR',
  71. ['*' ,'@token_definition'] ,'$RCBR'],
  72. 'errortext': 'Token collection definition' },
  73. 'token_collection_category': { 'type': 'prod', 'body': ['.', '$KEYWORDS'],
  74. 'errortext': 'Token collection categories: keywords' },
  75. 'collection_name': { 'type': 'prod', 'body': ['.', '$LOWER_CASE'] , 'errortext': 'Token collection name'},
  76. 'token_definition': { 'type': 'prod', 'body': [ '.', '@token_name', '$COLON', '@token_value',
  77. ['*',['|','@modifier','@message','@remove']], '$SEMICOL'],
  78. 'errortext': 'Token definition' },
  79. 'token_name': { 'type': 'prod', 'body': ['.', '$UPPER_CASE'] , 'errortext': 'Token name'},
  80. 'token_value': { 'type': 'prod', 'body': ['.', '$REGEXP'] , 'errortext': 'Token value'},
  81. 'modifier': { 'type': 'prod', 'body': ['.', '$IMPLICIT_MOD'] , 'errortext': 'Possible modifiers'},
  82. 'remove': { 'type': 'prod', 'body': ['.', '$REMOVE_MOD'] , 'errortext': 'Possible modifiers'},
  83. 'mapper': { 'type': 'prod', 'body': ['.', '$MAPPER','$LCBR', ['*', '@mapper_content'], '$RCBR'],
  84. 'errortext': 'Top level mapper definition'},
  85. 'mapper_content': { 'type': 'prod', 'body': ['.', 'TODO'], 'errortext': 'Content of the mapper' },
  86. 'implicit': {'type': 'prod', 'body':['*', ['|', '$NEWLINE', '$WS', '$LINE_CONT', '$COMMENT']],
  87. 'errortext': 'Implicit'}
  88. }