pascal.peg 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. # pascal language lexer+parser to use with packcc parser generator
  2. %prefix "pascal"
  3. %source{
  4. #include <stdio.h>
  5. static const char *dbg_str[] = { "Evaluating rule", "Matched rule", "Abandoning rule" };
  6. #define PCC_DEBUG(event, rule, level, pos, buffer, length) \
  7. fprintf(stdout, "%*s%s %s @%d [%.*s]\n", (int)(level * 2), "", dbg_str[event], rule, (int)pos, (int)length, buffer); fflush(stdout)
  8. /* NOTE: To guarantee the output order, stderr, which can lead a race condition with stdout, is not used. */
  9. }
  10. start <- program / unit _ !.
  11. program <- "program" __ identifier ";" _ block "."
  12. unit <- "unit" __ identifier ";" _ "interface" _ interface_part _ "implementation" _ implementation_part _ "end" "."
  13. uses <- "uses" _ identifier ("," _ identifier)* ";" _
  14. block <- declarations "begin" _ statements _ "end"
  15. statements <- (statement ";" _)*
  16. declarations <- declaration_part*
  17. declaration_part <- uses / types / constants / vars / procedure_declaration / function_declaration
  18. interface_part <- (uses / types / constants / vars / procedure_header / function_header)*
  19. implementation_part <- declarations
  20. procedure_header <- "procedure" _ identifier "(" argument_list_declaration ")" _ ";" _
  21. / "procedure" _ identifier _ ";" _
  22. procedure_declaration <- procedure_header _ block ";" _
  23. function_header <- "function" _ identifier "(" argument_list_declaration ")" _ ":" _ type ";" _
  24. / "function" _ identifier _ ":" _ type _ ";" _
  25. function_declaration <- function_header _ block ";" _
  26. argument_list_declaration <- argument_declaration? (";" _ argument_declaration)*
  27. argument_declaration <- "var"? _ identifier ("," _ identifier)* ":" _ type
  28. types <- "type" _ type_declaration+
  29. type_declaration <- identifier _ "=" _ type _ ";" _
  30. constants <- "const" _ constant+
  31. constant <- identifier _ "=" _ const_literal _ ";" _
  32. / identifier _ ":" _ type _ "=" _ const_literal _ ";" _
  33. const_literal <- literal
  34. / "(" _ argument_list _ ")"
  35. / "(" _ field_literal (";" _ field_literal)* ")"
  36. field_literal <- identifier _ ":" _ literal
  37. vars <- "var" _ var_declaration+
  38. var_declaration <- identifier ("," _ identifier)* ":" _ type _ ";" _
  39. type <- "array" _ "[" integer_literal _ ".." _ integer_literal _ "]" _ "of" _ type
  40. / "record" __ argument_list_declaration _ ";"? _ "end"
  41. / "^" type
  42. / identifier
  43. statement <- compound / procedure_call / assignment / if_else / if / for / while / repeat / with
  44. compound <- "begin" _ statements _ "end"
  45. assignment <- lvalue _ ":=" _ expression
  46. lvalue <- field_access / array_accesses
  47. field_access <- array_accesses "." lvalue
  48. array_accesses <- array_access / identifier
  49. array_access <- identifier "[" expression "]"
  50. procedure_call <- identifier _ "(" argument_list ")"
  51. argument_list <- argument? ("," _ argument)*
  52. argument <- expression
  53. if_else <- "if" _ expression _ "then" _ statement _ "else" _ statement
  54. if <- "if" _ expression _ "then" _ statement
  55. for <- "for" _ identifier _ ":=" _ expression _ ("to" / "downto") _ expression _ "do" _ statement
  56. while <- "while" _ expression _ "do" _ statement
  57. repeat <- "repeat" _ statements _ "until" _ expression
  58. with <- "with" __ lvalue __ "do" __ statement
  59. function_call <- identifier _ "(" argument_list ")"
  60. expression <- negation / comparision / or_expr
  61. negation <- "not" _ expression
  62. comparision <- or_expr _ "=" _ or_expr
  63. / or_expr _ "<>" _ or_expr
  64. / or_expr _ ">=" _ or_expr
  65. / or_expr _ "<=" _ or_expr
  66. / or_expr _ ">" _ or_expr
  67. / or_expr _ "<" _ or_expr
  68. or_binary <- and_expr _ ("or" / "+" / "-") _ or_expr
  69. or_expr <- or_binary / and_expr
  70. and_binary <- base_expr _ ("and" / "*" / "/" / "div" / "mod") _ and_expr
  71. and_expr <- and_binary / base_expr
  72. base_expr <- primary / nested_expression
  73. nested_expression <- "(" _ expression _ ")"
  74. primary <- function_call / pointer_to / deref / literal / lvalue
  75. pointer_to <- "@" identifier
  76. deref <- identifier "^"
  77. identifier <- [A-Za-z][A-Za-z0-9_]*
  78. literal <- string_literal / boolean_literal / real_literal / integer_literal
  79. string_literal <- "'" string_character* "'"
  80. string_character <- !("'") .
  81. boolean_literal <- "true" / "false"
  82. integer_literal <- "$" [0-9A-Fa-f]+
  83. / [0-9]+
  84. real_literal <- [0-9]+ "." [0-9]+
  85. comment <- "{" comment_character* "}"
  86. comment_character <- !("}") .
  87. _ <- (comment / [ \t\n\r])*
  88. __ <- (comment / [ \t\n\r])+
  89. %%
  90. int main() {
  91. pascal_context_t *ctx=pascal_create(NULL);
  92. while (pascal_parse(ctx, NULL)){;}
  93. pascal_destroy(ctx);
  94. return 0;
  95. }