1mod error;
17mod expression;
18mod statement;
19mod parser_expanded;
21use parser_expanded as parser;
22mod spannedstring;
23
24pub use spannedstring::SpannedString;
26
27pub use lua_tokenizer::FloatType;
28pub use lua_tokenizer::IntOrFloat;
29pub use lua_tokenizer::IntType;
30pub use lua_tokenizer::Span;
31pub use lua_tokenizer::Token;
32
33pub use error::InvalidToken;
34pub use error::ParseError;
35pub use error::TokenizeError;
36
37pub use expression::ExprBinary;
38pub use expression::ExprBinaryData;
39pub use expression::ExprBool;
40pub use expression::ExprFunction;
41pub use expression::ExprFunctionCall;
42pub use expression::ExprIdent;
43pub use expression::ExprNil;
44pub use expression::ExprNumeric;
45pub use expression::ExprString;
46pub use expression::ExprTable;
47pub use expression::ExprTableIndex;
48pub use expression::ExprUnary;
49pub use expression::ExprUnaryData;
50pub use expression::ExprVariadic;
51pub use expression::Expression;
52pub use expression::FunctionCallArguments;
53pub use expression::ParameterList;
54pub use expression::TableField;
55pub use expression::TableFieldKeyValue;
56pub use expression::TableFieldNameValue;
57pub use expression::TableFieldValue;
58
59pub use statement::AttName;
60pub use statement::Attrib;
61pub use statement::Block;
62pub use statement::FunctionName;
63pub use statement::ReturnStatement;
64pub use statement::Statement;
65pub use statement::StmtAssignment;
66pub use statement::StmtBreak;
67pub use statement::StmtDo;
68pub use statement::StmtElseIf;
69pub use statement::StmtFor;
70pub use statement::StmtForGeneric;
71pub use statement::StmtFunctionCall;
72pub use statement::StmtFunctionDefinition;
73pub use statement::StmtFunctionDefinitionLocal;
74pub use statement::StmtGoto;
75pub use statement::StmtIf;
76pub use statement::StmtLabel;
77pub use statement::StmtLocalDeclaration;
78pub use statement::StmtNone;
79pub use statement::StmtRepeat;
80pub use statement::StmtWhile;
81
82pub use lua_tokenizer::Tokenizer;
83
84pub use parser::ChunkOrExpressionsContext as Context;
85pub use parser::ChunkOrExpressionsParser as Parser;
86
87#[derive(Debug, Clone)]
89pub enum ChunkOrExpressions {
90 Chunk(Block),
91 Expressions(Vec<Expression>),
92}
93
94pub fn parse_str(source: &str) -> Result<Block, ParseError> {
96 parse_bytes(source.as_bytes())
97}
98
99pub fn parse_bytes(source: &[u8]) -> Result<Block, ParseError> {
101 let tokenizer = Tokenizer::from_bytes(source);
102 let parser = parser::ChunkOrExpressionsParser::new();
103 let mut context = parser::ChunkOrExpressionsContext::new();
104
105 for token in tokenizer.into_iter() {
106 let token = match token {
107 Ok(token) => token,
108 Err(e) => {
109 return Err(ParseError::TokenizeError(e));
110 }
111 };
112
113 match context.feed(&parser, token, &mut ()) {
114 Ok(_) => {}
115 Err(err) => {
116 let (expected_terms, expected_nonterms) = context.expected_token_str(&parser);
117 let error = InvalidToken {
118 token: Some(err.term.into_term().unwrap()),
119 expected: expected_terms.collect(),
120 expected_nonterm: expected_nonterms.collect(),
121 };
122 return Err(ParseError::InvalidToken(error));
123 }
127 }
128 }
129
130 let mut block = None;
131
132 let (expected_terms, expected_nonterms) = context.expected_token_str(&parser);
133 let res = context.accept(&parser, &mut ());
134 match res {
135 Ok(matched) => {
136 for matched in matched {
137 match matched {
138 ChunkOrExpressions::Chunk(block_) => {
139 if block.is_some() {
140 return Err(ParseError::Ambiguous);
141 }
142 block = Some(block_);
143 }
144 _ => {}
145 }
146 }
147 }
148 Err(_) => {
149 let error = InvalidToken {
150 token: None,
151 expected: expected_terms.collect(),
152 expected_nonterm: expected_nonterms.collect(),
153 };
154 return Err(ParseError::InvalidToken(error));
155 }
156 }
157
158 if let Some(block) = block {
159 Ok(block)
160 } else {
161 Err(ParseError::Ambiguous)
162 }
163}